Changeset 32425 in vbox for trunk/src/VBox/Additions/WINNT/Graphics/Display
- Timestamp:
- Sep 10, 2010 7:43:11 PM (14 years ago)
- Location:
- trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp
r32325 r32425 868 868 { 869 869 pRc->cAllocations = cAllocs; 870 for (UINT i = 0; i < cAllocs; ++i) 871 { 872 pRc->aAllocations[i].pRc = pRc; 873 } 870 874 return pRc; 871 875 } … … 1097 1101 } 1098 1102 1099 1103 #if 0 1100 1104 static HRESULT vboxWddmRenderTargetUpdateSurface(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, uint32_t iBBuf) 1101 1105 { … … 1175 1179 return S_OK; 1176 1180 } 1177 1178 #ifdef DEBUG1179 static void vboxWddmDbgRenderTargetUpdateCheckSurface(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, uint32_t iBBuf)1180 {1181 IDirect3DSurface9 *pD3D9Surf;1182 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);1183 IDirect3DDevice9 * pDevice9If = pDevice->aScreens[pDevice->iPrimaryScreen].pDevice9If;1184 HRESULT hr = pDevice9If->GetBackBuffer(0 /*UINT iSwapChain*/,1185 iBBuf, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);1186 Assert(hr == S_OK);1187 if (hr == S_OK)1188 {1189 Assert(pD3D9Surf);1190 Assert(pD3D9Surf == pAlloc->pD3DIf);1191 pD3D9Surf->Release();1192 }1193 }1194 1195 static void vboxWddmDbgRenderTargetCheck(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc, uint32_t iNewRTFB)1196 {1197 PVBOXWDDMDISP_ALLOCATION pAlloc;1198 UINT iBBuf = 0;1199 Assert(iNewRTFB < pRc->cAllocations);1200 1201 for (UINT i = 1; i < pRc->cAllocations; ++i, ++iBBuf)1202 {1203 UINT iAlloc = (iNewRTFB + i) % pRc->cAllocations;1204 Assert(iAlloc != iNewRTFB);1205 pAlloc = &pRc->aAllocations[iAlloc];1206 vboxWddmDbgRenderTargetUpdateCheckSurface(pDevice, pAlloc, iBBuf);1207 }1208 1209 pAlloc = &pRc->aAllocations[iNewRTFB];1210 #ifdef VBOXWDDM_WITH_VISIBLE_FB1211 vboxWddmDbgRenderTargetUpdateCheckSurface(pDevice, pAlloc, ~0UL /* <- for the frontbuffer */);1212 #else1213 Assert((!pAlloc->pD3DIf) == (pRc->cAllocations > 1));1214 1181 #endif 1215 1216 for (UINT i = 0; i < pRc->cAllocations; ++i)1217 {1218 pAlloc = &pRc->aAllocations[i];1219 if (iNewRTFB == i)1220 {1221 Assert((!pAlloc->pD3DIf) == (pRc->cAllocations > 1));1222 }1223 1224 for (UINT j = i+1; j < pRc->cAllocations; ++j)1225 {1226 PVBOXWDDMDISP_ALLOCATION pAllocJ = &pRc->aAllocations[j];1227 Assert(pAlloc->pD3DIf != pAllocJ->pD3DIf);1228 }1229 }1230 }1231 1232 # define VBOXVDBG_RTGT_STATECHECK(_pDev) (vboxWddmDbgRenderTargetCheck((_pDev), (_pDev)->aScreens[(_pDev)->iPrimaryScreen].pRenderTargetRc, (_pDev)->aScreens[(_pDev)->iPrimaryScreen].iRenderTargetFrontBuf))1233 #else1234 # define VBOXVDBG_RTGT_STATECHECK(_pDev) do{}while(0)1235 #endif1236 1237 static HRESULT vboxWddmD3DDeviceCreate(PVBOXWDDMDISP_DEVICE pDevice, UINT iScreen, PVBOXWDDMDISP_RESOURCE pRc, D3DPRESENT_PARAMETERS * pParams, BOOL bLockable)1238 {1239 UINT cSurfs = pParams->BackBufferCount + 1;1240 Assert(pRc->cAllocations = cSurfs);1241 IDirect3DDevice9 *pPrimaryDevice = pDevice->aScreens[pDevice->iPrimaryScreen].pDevice9If;1242 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[iScreen];1243 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;1244 HRESULT hr;1245 HWND hWnd = NULL;1246 Assert(!pScreen->pDevice9If);1247 Assert(!pScreen->hWnd);1248 hr = VBoxDispWndCreate(pAdapter, pParams->BackBufferWidth, pParams->BackBufferHeight, &hWnd);1249 Assert(hr == S_OK);1250 if (hr == S_OK)1251 {1252 pScreen->hWnd = hWnd;1253 1254 DWORD fFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;1255 if (pDevice->fFlags.AllowMultithreading)1256 fFlags |= D3DCREATE_MULTITHREADED;1257 1258 IDirect3DDevice9 *pDevice9If = NULL;1259 pParams->hDeviceWindow = hWnd;1260 /* @todo: it seems there should be a way to detect this correctly since1261 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */1262 pParams->Windowed = TRUE;1263 // params.EnableAutoDepthStencil = FALSE;1264 // params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;1265 // params.Flags;1266 // params.FullScreen_RefreshRateInHz;1267 // params.FullScreen_PresentationInterval;1268 hr = pAdapter->pD3D9If->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, fFlags, pParams, &pDevice9If);1269 Assert(hr == S_OK);1270 if (hr == S_OK)1271 {1272 pScreen->pDevice9If = pDevice9If;1273 pScreen->pRenderTargetRc = pRc;1274 ++pDevice->cScreens;1275 1276 for (UINT i = 0; i < cSurfs; ++i)1277 {1278 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];1279 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;1280 }1281 1282 if (pPrimaryDevice)1283 {1284 for (UINT i = 0; i < cSurfs; ++i)1285 {1286 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];1287 IDirect3DSurface9 *pRt;1288 IDirect3DSurface9 *pSecondaryOpenedRt;1289 HANDLE hSharedHandle = NULL;1290 hr = pPrimaryDevice->CreateRenderTarget(1291 pParams->BackBufferWidth, pParams->BackBufferHeight,1292 pParams->BackBufferFormat,1293 pParams->MultiSampleType,1294 pParams->MultiSampleQuality,1295 TRUE, /*BOOL Lockable*/1296 &pRt,1297 &hSharedHandle);1298 Assert(hr == S_OK);1299 if (hr == S_OK)1300 {1301 Assert(hSharedHandle != NULL);1302 /* open render target for primary device */1303 hr = pDevice9If->CreateRenderTarget(1304 pParams->BackBufferWidth, pParams->BackBufferHeight,1305 pParams->BackBufferFormat,1306 pParams->MultiSampleType,1307 pParams->MultiSampleQuality,1308 TRUE, /*BOOL Lockable*/1309 &pSecondaryOpenedRt,1310 &hSharedHandle);1311 Assert(hr == S_OK);1312 if (hr == S_OK)1313 {1314 pAllocation->pD3DIf = pRt;1315 pAllocation->pSecondaryOpenedD3DIf = pSecondaryOpenedRt;1316 pAllocation->hSharedHandle = hSharedHandle;1317 continue;1318 }1319 pRt->Release();1320 }1321 1322 for (UINT j = 0; j < i; ++j)1323 {1324 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[j];1325 pAlloc->pD3DIf->Release();1326 pAlloc->pSecondaryOpenedD3DIf->Release();1327 }1328 1329 break;1330 }1331 }1332 else1333 {1334 pDevice->iPrimaryScreen = iScreen;1335 hr = vboxWddmRenderTargetUpdate(pDevice, pRc, 0);1336 Assert(hr == S_OK);1337 }1338 1339 if (hr == S_OK)1340 {1341 for (UINT i = 0; i < cSurfs; ++i)1342 {1343 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];1344 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;1345 hr = vboxWddmSurfSynchMem(pRc, pAllocation);1346 Assert(hr == S_OK);1347 if (hr != S_OK)1348 {1349 break;1350 }1351 }1352 1353 #ifndef VBOXWDDM_WITH_VISIBLE_FB1354 if (!pPrimaryDevice)1355 {1356 if (hr == S_OK)1357 {1358 IDirect3DSurface9* pD3D9Surf;1359 hr = pDevice9If->CreateRenderTarget(1360 pParams->BackBufferWidth, pParams->BackBufferHeight,1361 pParams->BackBufferFormat,1362 pParams->MultiSampleType,1363 pParams->MultiSampleQuality,1364 bLockable,1365 &pD3D9Surf,1366 NULL /* HANDLE* pSharedHandle */1367 );1368 Assert(hr == S_OK);1369 if (hr == S_OK)1370 {1371 pDevice->pRenderTargetFbCopy = pD3D9Surf;1372 }1373 }1374 }1375 #endif1376 1377 if (hr != S_OK)1378 {1379 for (UINT i = 0; i < cSurfs; ++i)1380 {1381 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];1382 pAllocation->pD3DIf->Release();1383 }1384 }1385 }1386 1387 if (hr != S_OK)1388 {1389 pDevice9If->Release();1390 --pDevice->cScreens;1391 Assert(pDevice->cScreens < UINT32_MAX/2);1392 }1393 }1394 1395 if (hr != S_OK)1396 {1397 HRESULT tmpHr = VBoxDispWndDestroy(pAdapter, pScreen->hWnd);1398 Assert(tmpHr == S_OK);1399 }1400 }1401 1402 return hr;1403 }1404 1405 static HRESULT vboxWddmD3DDeviceCreateDummy(PVBOXWDDMDISP_DEVICE pDevice)1406 {1407 HRESULT hr;1408 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(2);1409 Assert(pRc);1410 if (pRc)1411 {1412 D3DPRESENT_PARAMETERS params;1413 memset(¶ms, 0, sizeof (params));1414 // params.BackBufferWidth = 640;1415 // params.BackBufferHeight = 480;1416 params.BackBufferWidth = 0x400;1417 params.BackBufferHeight = 0x300;1418 params.BackBufferFormat = D3DFMT_A8R8G8B8;1419 // params.BackBufferCount = 0;1420 params.BackBufferCount = 1;1421 params.MultiSampleType = D3DMULTISAMPLE_NONE;1422 params.SwapEffect = D3DSWAPEFFECT_DISCARD;1423 // params.hDeviceWindow = hWnd;1424 /* @todo: it seems there should be a way to detect this correctly since1425 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */1426 params.Windowed = TRUE;1427 // params.EnableAutoDepthStencil = FALSE;1428 // params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;1429 // params.Flags;1430 // params.FullScreen_RefreshRateInHz;1431 // params.FullScreen_PresentationInterval;1432 1433 hr = vboxWddmD3DDeviceCreate(pDevice, 0, pRc, ¶ms, TRUE /*BOOL bLockable*/);1434 Assert(hr == S_OK);1435 if (hr != S_OK)1436 vboxResourceFree(pRc);1437 }1438 else1439 {1440 hr = E_OUTOFMEMORY;1441 }1442 1443 return hr;1444 }1445 1446 DECLINLINE(IDirect3DDevice9*) vboxWddmD3DDeviceGetPrimary(PVBOXWDDMDISP_DEVICE pDevice)1447 {1448 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];1449 if (pScreen->pDevice9If)1450 return pScreen->pDevice9If;1451 HRESULT hr = vboxWddmD3DDeviceCreateDummy(pDevice);1452 Assert(hr == S_OK);1453 Assert(pScreen->pDevice9If);1454 return pScreen->pDevice9If;1455 }1456 1457 static HRESULT APIENTRY vboxWddmDDevDestroyResource(HANDLE hDevice, HANDLE hResource);1458 1459 static HRESULT vboxWddmD3DDeviceUpdate(PVBOXWDDMDISP_DEVICE pDevice, UINT iScreen, PVBOXWDDMDISP_RESOURCE pRc, D3DPRESENT_PARAMETERS * pParams, BOOL bLockable)1460 {1461 UINT cSurfs = pParams->BackBufferCount + 1;1462 Assert(pRc->cAllocations = cSurfs);1463 Assert(iScreen == pDevice->iPrimaryScreen);1464 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[iScreen];1465 PVBOXWDDMDISP_RESOURCE pCurRc = pScreen->pRenderTargetRc;1466 IDirect3DDevice9Ex *pNewDevice;1467 HRESULT hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9Update((IDirect3DDevice9Ex*)pScreen->pDevice9If, pParams, &pNewDevice);1468 Assert(hr == S_OK);1469 if (hr == S_OK)1470 {1471 pScreen->pDevice9If->Release();1472 pScreen->pDevice9If = pNewDevice;1473 pScreen->pRenderTargetRc = pRc;1474 1475 for (UINT i = 0; i < cSurfs; ++i)1476 {1477 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];1478 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;1479 }1480 1481 #ifndef VBOXWDDM_WITH_VISIBLE_FB1482 if (pDevice->pRenderTargetFbCopy)1483 {1484 pDevice->pRenderTargetFbCopy->Release();1485 }1486 IDirect3DSurface9* pD3D9Surf;1487 hr = pNewDevice->CreateRenderTarget(1488 pParams->BackBufferWidth, pParams->BackBufferHeight,1489 pParams->BackBufferFormat,1490 pParams->MultiSampleType,1491 pParams->MultiSampleQuality,1492 bLockable,1493 &pD3D9Surf,1494 NULL /* HANDLE* pSharedHandle */1495 );1496 Assert(hr == S_OK);1497 if (hr == S_OK)1498 {1499 pDevice->pRenderTargetFbCopy = pD3D9Surf;1500 }1501 #endif1502 if (hr == S_OK)1503 {1504 hr = vboxWddmRenderTargetUpdate(pDevice, pRc, 0);1505 Assert(hr == S_OK);1506 if (hr == S_OK)1507 {1508 for (UINT i = 0; i < cSurfs; ++i)1509 {1510 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];1511 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;1512 hr = vboxWddmSurfSynchMem(pRc, pAllocation);1513 Assert(hr == S_OK);1514 if (hr != S_OK)1515 {1516 break;1517 }1518 }1519 }1520 }1521 }1522 1523 1524 if (!pCurRc->hResource)1525 {1526 HRESULT tmpHr = vboxWddmDDevDestroyResource(pDevice, pCurRc);1527 Assert(tmpHr == S_OK);1528 }1529 1530 return hr;1531 }1532 1182 1533 1183 static D3DFORMAT vboxDDI2D3DFormat(D3DDDIFORMAT format) … … 1678 1328 return D3DTEXF_NONE; 1679 1329 } 1330 1331 1332 /******/ 1333 DECLINLINE(VOID) vboxWddmSwapchainInit(PVBOXWDDMDISP_SWAPCHAIN pSwapchain) 1334 { 1335 RTLISTNODE ListEntry = pSwapchain->ListEntry; 1336 memset(pSwapchain, 0, sizeof (VBOXWDDMDISP_SWAPCHAIN)); 1337 pSwapchain->ListEntry = ListEntry; 1338 pSwapchain->iBB = VBOXWDDMDISP_INDEX_UNDEFINED; 1339 } 1340 1341 static HRESULT vboxWddmSwapchainDestroyIf(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain) 1342 { 1343 if (pSwapchain->pSwapChainIf) 1344 { 1345 pSwapchain->pRenderTargetFbCopy->Release(); 1346 pSwapchain->pSwapChainIf->Release(); 1347 Assert(pSwapchain->hWnd); 1348 HRESULT hr = VBoxDispWndDestroy(pDevice->pAdapter, pSwapchain->hWnd); 1349 Assert(hr == S_OK); 1350 pSwapchain->pRenderTargetFbCopy = NULL; 1351 pSwapchain->pSwapChainIf = NULL; 1352 pSwapchain->hWnd = NULL; 1353 return hr; 1354 } 1355 1356 Assert(!pSwapchain->hWnd); 1357 return S_OK; 1358 } 1359 1360 DECLINLINE(VOID) vboxWddmSwapchainClear(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain) 1361 { 1362 for (UINT i = 0; i < pSwapchain->cRTs; ++i) 1363 { 1364 pSwapchain->aRTs[i].pAlloc->pSwapchain = NULL; 1365 } 1366 vboxWddmSwapchainDestroyIf(pDevice, pSwapchain); 1367 vboxWddmSwapchainInit(pSwapchain); 1368 } 1369 1370 static VOID vboxWddmSwapchainDestroy(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain) 1371 { 1372 vboxWddmSwapchainClear(pDevice, pSwapchain); 1373 RTListNodeRemove(&pSwapchain->ListEntry); 1374 RTMemFree(pSwapchain); 1375 } 1376 1377 static VOID vboxWddmSwapchainDestroyAll(PVBOXWDDMDISP_DEVICE pDevice) 1378 { 1379 PVBOXWDDMDISP_SWAPCHAIN pCur = RTListNodeGetFirst(&pDevice->SwapchainList, VBOXWDDMDISP_SWAPCHAIN, ListEntry); 1380 while (pCur) 1381 { 1382 PVBOXWDDMDISP_SWAPCHAIN pNext = NULL; 1383 if (!RTListNodeIsLast(&pDevice->SwapchainList, &pCur->ListEntry)) 1384 { 1385 pNext = RTListNodeGetNext(&pCur->ListEntry, VBOXWDDMDISP_SWAPCHAIN, ListEntry); 1386 } 1387 1388 vboxWddmSwapchainDestroy(pDevice, pCur); 1389 1390 pCur = pNext; 1391 } 1392 } 1393 1394 static PVBOXWDDMDISP_SWAPCHAIN vboxWddmSwapchainAlloc(PVBOXWDDMDISP_DEVICE pDevice) 1395 { 1396 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = (PVBOXWDDMDISP_SWAPCHAIN)RTMemAllocZ(sizeof (VBOXWDDMDISP_SWAPCHAIN)); 1397 Assert(pSwapchain); 1398 if (pSwapchain) 1399 { 1400 RTListAppend(&pDevice->SwapchainList, &pSwapchain->ListEntry); 1401 vboxWddmSwapchainInit(pSwapchain); 1402 return pSwapchain; 1403 } 1404 return NULL; 1405 } 1406 1407 DECLINLINE(VOID) vboxWddmSwapchainRtInit(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRt, PVBOXWDDMDISP_ALLOCATION pAlloc) 1408 { 1409 pSwapchain->fFlags.bChanged = 1; 1410 pRt->pAlloc = pAlloc; 1411 pRt->cNumFlips = 0; 1412 pRt->fFlags.Value = 0; 1413 pRt->fFlags.bAdded = 1; 1414 } 1415 1416 DECLINLINE(VOID) vboxWddmSwapchainBbAddTail(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bAssignAsBb) 1417 { 1418 pAlloc->pSwapchain = pSwapchain; 1419 VBOXWDDMDISP_SWAPCHAIN_FLAGS fOldFlags = pSwapchain->fFlags; 1420 PVBOXWDDMDISP_RENDERTGT pRt = &pSwapchain->aRTs[pSwapchain->cRTs]; 1421 ++pSwapchain->cRTs; 1422 vboxWddmSwapchainRtInit(pSwapchain, pRt, pAlloc); 1423 if (pSwapchain->cRTs == 1) 1424 { 1425 Assert(pSwapchain->iBB == VBOXWDDMDISP_INDEX_UNDEFINED); 1426 pSwapchain->iBB = 0; 1427 } 1428 else if (bAssignAsBb) 1429 { 1430 pSwapchain->iBB = pSwapchain->cRTs - 1; 1431 } 1432 else if (pSwapchain->cRTs == 2) /* the first one is a frontbuffer */ 1433 { 1434 pSwapchain->iBB = 1; 1435 } 1436 } 1437 1438 DECLINLINE(UINT) vboxWddmSwapchainIdxFb(PVBOXWDDMDISP_SWAPCHAIN pSwapchain) 1439 { 1440 return (pSwapchain->iBB + pSwapchain->cRTs - 1) % pSwapchain->cRTs; 1441 } 1442 1443 /* if swapchain contains only one surface returns this surface */ 1444 DECLINLINE(PVBOXWDDMDISP_RENDERTGT) vboxWddmSwapchainGetBb(PVBOXWDDMDISP_SWAPCHAIN pSwapchain) 1445 { 1446 if (pSwapchain->cRTs) 1447 { 1448 Assert(pSwapchain->iBB < pSwapchain->cRTs); 1449 return &pSwapchain->aRTs[pSwapchain->iBB]; 1450 } 1451 return NULL; 1452 } 1453 1454 DECLINLINE(PVBOXWDDMDISP_RENDERTGT) vboxWddmSwapchainGetFb(PVBOXWDDMDISP_SWAPCHAIN pSwapchain) 1455 { 1456 if (pSwapchain->cRTs) 1457 { 1458 UINT iFb = vboxWddmSwapchainIdxFb(pSwapchain); 1459 return &pSwapchain->aRTs[iFb]; 1460 } 1461 return NULL; 1462 } 1463 1464 DECLINLINE(VOID) vboxWddmSwapchainFlip(PVBOXWDDMDISP_SWAPCHAIN pSwapchain) 1465 { 1466 pSwapchain->iBB = (pSwapchain->iBB + 1) % pSwapchain->cRTs; 1467 } 1468 1469 DECLINLINE(UINT) vboxWddmSwapchainNumRTs(PVBOXWDDMDISP_SWAPCHAIN pSwapchain) 1470 { 1471 return pSwapchain->cRTs; 1472 } 1473 1474 1475 DECLINLINE(PVBOXWDDMDISP_RENDERTGT) vboxWddmSwapchainRtForAlloc(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_ALLOCATION pAlloc) 1476 { 1477 if (pAlloc->pSwapchain != pSwapchain) 1478 return NULL; 1479 1480 for (UINT i = 0; i < pSwapchain->cRTs; ++i) 1481 { 1482 Assert(pSwapchain->aRTs[i].pAlloc->pSwapchain = pSwapchain); 1483 if (pSwapchain->aRTs[i].pAlloc == pAlloc) 1484 return &pSwapchain->aRTs[i]; 1485 } 1486 1487 /* should never happen */ 1488 Assert(0); 1489 return NULL; 1490 } 1491 1492 DECLINLINE(UINT) vboxWddmSwapchainRtIndex(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRT) 1493 { 1494 UINT offFirst = RT_OFFSETOF(VBOXWDDMDISP_SWAPCHAIN, aRTs); 1495 UINT offRT = UINT((uintptr_t)pRT - (uintptr_t)pSwapchain); 1496 Assert(offRT < sizeof (VBOXWDDMDISP_SWAPCHAIN)); 1497 Assert(offRT >= offFirst); 1498 Assert(!((offRT - offFirst) % sizeof (VBOXWDDMDISP_RENDERTGT))); 1499 UINT iRt = (offRT - offFirst) / sizeof (VBOXWDDMDISP_RENDERTGT); 1500 Assert(iRt < pSwapchain->cRTs); 1501 return iRt; 1502 } 1503 1504 DECLINLINE(PVBOXWDDMDISP_SWAPCHAIN) vboxWddmSwapchainForAlloc(PVBOXWDDMDISP_ALLOCATION pAlloc) 1505 { 1506 return pAlloc->pSwapchain; 1507 } 1508 1509 DECLINLINE(VOID) vboxWddmSwapchainRtRemove(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRT) 1510 { 1511 UINT iRt = vboxWddmSwapchainRtIndex(pSwapchain, pRT); 1512 Assert(iRt < pSwapchain->cRTs); 1513 pRT->pAlloc->pSwapchain = NULL; 1514 for (UINT i = iRt; i < pSwapchain->cRTs - 1; ++i) 1515 { 1516 pSwapchain->aRTs[i] = pSwapchain->aRTs[i + 1]; 1517 } 1518 1519 --pSwapchain->cRTs; 1520 if (pSwapchain->cRTs) 1521 { 1522 if (pSwapchain->iBB > iRt) 1523 { 1524 --pSwapchain->iBB; 1525 } 1526 else if (pSwapchain->iBB == iRt) 1527 { 1528 Assert(0); 1529 pSwapchain->iBB = 0; 1530 } 1531 } 1532 else 1533 { 1534 pSwapchain->iBB = VBOXWDDMDISP_INDEX_UNDEFINED; 1535 } 1536 pSwapchain->fFlags.bChanged = TRUE; 1537 } 1538 1539 #if 0 1540 1541 1542 DECLINLINE(VOID) vboxWddmSwapchainSetBb(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRT) 1543 { 1544 UINT iRt = vboxWddmSwapchainRtIndex(pSwapchain, pRT); 1545 Assert(iRt < pSwapchain->cRTs); 1546 pSwapchain->iBB = iRt; 1547 } 1548 1549 /* the paRemoved buffer should at least contain VBOXWDDMDISP_MAX_SWAPCHAIN_SIZE elements, 1550 * the function does not validate its size in any way */ 1551 static BOOL vboxWddmSwapchainAdjust(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_ALLOCATION pBbAlloc, PUINT pcRemoved, PVBOXWDDMDISP_ALLOCATION paRemoved) 1552 { 1553 UINT cRemoved = 0; 1554 BOOL bChanged = FALSE; 1555 PVBOXWDDMDISP_RENDERTGT pCurBbRt = vboxWddmSwapchainGetBb(pSwapchain); 1556 if (pCurBb) 1557 { 1558 if (pCurBbRt->pAlloc != pBbAlloc) 1559 { 1560 bChanged = TRUE; 1561 1562 /* determine whether we need to add the current BB 1563 * or remove part or all of the current RTs in the swapchain */ 1564 PVBOXWDDMDISP_RENDERTGT pCorrectRt = vboxWddmSwapchainSearchRt(pSwapchain, pBbAlloc); 1565 if (pCorrectRt) 1566 { 1567 paRemoved[cRemoved] = pCurBbRt->pAlloc; 1568 ++cRemoved; 1569 vboxWddmSwapchainRemoveRt(pSwapchain, pCurBbRt); 1570 vboxWddmSwapchainSetBb(pSwapchain, pBbAlloc); 1571 } 1572 else 1573 { 1574 /* check if the pCurBbRt stored in the swapchain match those of the pBbAlloc */ 1575 if (pBbAlloc->SurfDesc.width == pCurBbRt->pAlloc->SurfDesc.width 1576 && pBbAlloc->SurfDesc.height == pCurBbRt->pAlloc->SurfDesc.height 1577 && pBbAlloc->SurfDesc.format == pCurBbRt->pAlloc->SurfDesc.format) 1578 { 1579 for (UINT i = 0; i < pSwapchain->cRTs;) 1580 { 1581 if (pSwapchain->aRTs[i].cNumFlips > 1) 1582 { 1583 paRemoved[cRemoved] = pSwapchain->aRTs[i].pAlloc; 1584 ++cRemoved; 1585 vboxWddmSwapchainRemoveRt(pSwapchain, &pSwapchain->aRTs[i]); 1586 } 1587 else 1588 { 1589 ++i; 1590 } 1591 } 1592 } 1593 else 1594 { 1595 /* remove all */ 1596 for (UINT i = 0; i < pSwapchain->cRTs; ++i) 1597 { 1598 paRemoved[cRemoved] = pSwapchain->aRTs[i].pAlloc; 1599 ++cRemoved; 1600 } 1601 1602 vboxWddmSwapchainClear(pSwapchain); 1603 } 1604 1605 vboxWddmSwapchainAllocAddTail(pSwapchain, pBbAlloc); 1606 vboxWddmSwapchainSetBb(pSwapchain, pBbAlloc); 1607 } 1608 } 1609 } 1610 else 1611 { 1612 vboxWddmSwapchainAllocAddTail(pSwapchain, pBbAlloc); 1613 bChanged = TRUE; 1614 } 1615 1616 if (!bChanged) 1617 { 1618 Assert(cRemoved == 0); 1619 } 1620 1621 *pcRemoved = cRemoved; 1622 1623 return bChanged; 1624 } 1625 #endif 1626 static PVBOXWDDMDISP_SWAPCHAIN vboxWddmSwapchainFindCreate(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pBbAlloc) 1627 { 1628 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = pBbAlloc->pSwapchain; 1629 if (pSwapchain) 1630 { 1631 /* check if this is what we expect */ 1632 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainGetBb(pSwapchain); 1633 if (pRt->pAlloc != pBbAlloc) 1634 { 1635 /* bad, @todo: correct the swapchain by either removing the Rt and adding it to another swapchain 1636 * or by removing the pBbAlloc out of it */ 1637 Assert(0); 1638 } 1639 } 1640 if (!pSwapchain) 1641 { 1642 Assert(0); 1643 /* first search for the swapchain the alloc might be added to */ 1644 PVBOXWDDMDISP_SWAPCHAIN pCur = RTListNodeGetFirst(&pDevice->SwapchainList, VBOXWDDMDISP_SWAPCHAIN, ListEntry); 1645 while (pCur) 1646 { 1647 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainGetBb(pCur); 1648 Assert(pRt); 1649 if (pRt->cNumFlips < 2 1650 && vboxWddmSwapchainRtIndex(pCur, pRt) == 0) /* <- in case we add a rt to the swapchain on present this would mean 1651 * that the last RT in the swapchain array is now a frontbuffer and 1652 * thus the aRTs[0] is a backbuffer */ 1653 { 1654 PVBOXWDDMDISP_RESOURCE pBbRc = pBbAlloc->pRc; 1655 PVBOXWDDMDISP_RESOURCE pRtRc = pRt->pAlloc->pRc; 1656 if (pBbAlloc->SurfDesc.width == pRt->pAlloc->SurfDesc.width 1657 && pBbAlloc->SurfDesc.height == pRt->pAlloc->SurfDesc.height 1658 && pBbAlloc->SurfDesc.format == pRt->pAlloc->SurfDesc.format 1659 && pBbAlloc->SurfDesc.VidPnSourceId == pRt->pAlloc->SurfDesc.VidPnSourceId 1660 && (pBbRc == pRtRc 1661 || (pBbRc->fFlags == pRtRc->fFlags 1662 && pBbRc->RcDesc.enmPool == pRtRc->RcDesc.enmPool 1663 && pBbRc->RcDesc.fFlags.Value == pRtRc->RcDesc.fFlags.Value 1664 ) 1665 )) 1666 { 1667 vboxWddmSwapchainBbAddTail(pCur, pBbAlloc, TRUE); 1668 pSwapchain = pCur; 1669 break; 1670 } 1671 } 1672 if (RTListNodeIsLast(&pDevice->SwapchainList, &pCur->ListEntry)) 1673 break; 1674 pCur = RTListNodeGetNext(&pCur->ListEntry, VBOXWDDMDISP_SWAPCHAIN, ListEntry); 1675 } 1676 1677 // if (!pSwapchain) need to create a new one (see below) 1678 } 1679 1680 if (!pSwapchain) 1681 { 1682 pSwapchain = vboxWddmSwapchainAlloc(pDevice); 1683 Assert(pSwapchain); 1684 if (pSwapchain) 1685 { 1686 vboxWddmSwapchainBbAddTail(pSwapchain, pBbAlloc, FALSE); 1687 } 1688 } 1689 1690 return pSwapchain; 1691 } 1692 1693 static PVBOXWDDMDISP_SWAPCHAIN vboxWddmSwapchainCreateForRc(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc) 1694 { 1695 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainAlloc(pDevice); 1696 Assert(pSwapchain); 1697 if (pSwapchain) 1698 { 1699 for (UINT i = 0; i < pRc->cAllocations; ++i) 1700 { 1701 vboxWddmSwapchainBbAddTail(pSwapchain, &pRc->aAllocations[i], FALSE); 1702 } 1703 return pSwapchain; 1704 } 1705 return NULL; 1706 } 1707 1708 DECLINLINE(UINT) vboxWddmSwapchainIdxBb2Rt(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, uint32_t iBb) 1709 { 1710 return iBb != (~0) ? (iBb + pSwapchain->iBB) % pSwapchain->cRTs : vboxWddmSwapchainIdxFb(pSwapchain); 1711 } 1712 1713 static HRESULT vboxWddmSwapchainRtSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain, uint32_t iBb, BOOL bSynchContents) 1714 { 1715 IDirect3DSurface9 *pD3D9Surf; 1716 UINT iRt = vboxWddmSwapchainIdxBb2Rt(pSwapchain, iBb); 1717 PVBOXWDDMDISP_RENDERTGT pRt = &pSwapchain->aRTs[iRt]; 1718 HRESULT hr = pSwapchain->pSwapChainIf->GetBackBuffer(iBb, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf); 1719 Assert(hr == S_OK); 1720 if (hr == S_OK) 1721 { 1722 PVBOXWDDMDISP_ALLOCATION pAlloc = pRt->pAlloc; 1723 Assert(pD3D9Surf); 1724 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE); 1725 if (pAlloc->pD3DIf) 1726 { 1727 if (bSynchContents) 1728 { 1729 IDirect3DSurface9 *pD3D9OldSurf = (IDirect3DSurface9*)pAlloc->pD3DIf; 1730 hr = pDevice->pDevice9If->StretchRect(pD3D9OldSurf, NULL, pD3D9Surf, NULL, D3DTEXF_NONE); 1731 Assert(hr == S_OK); 1732 } 1733 pAlloc->pD3DIf->Release(); 1734 } 1735 pAlloc->pD3DIf = pD3D9Surf; 1736 pRt->fFlags.Value = 0; 1737 } 1738 return hr; 1739 } 1740 static HRESULT vboxWddmSwapchainSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain) 1741 { 1742 BOOL bSynchContents = pSwapchain->fFlags.bChanged && pSwapchain->fFlags.bInited; 1743 for (int iBb = -1; iBb < int(pSwapchain->cRTs - 1); ++iBb) 1744 { 1745 HRESULT hr = vboxWddmSwapchainRtSynch(pDevice, pSwapchain, (UINT)iBb, bSynchContents); 1746 Assert(hr == S_OK); 1747 } 1748 pSwapchain->fFlags.bChanged = 0; 1749 pSwapchain->fFlags.bInited = 1; 1750 return S_OK; 1751 } 1752 1753 static VOID vboxWddmSwapchainFillParams(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, D3DPRESENT_PARAMETERS *pParams) 1754 { 1755 memset(pParams, 0, sizeof (D3DPRESENT_PARAMETERS)); 1756 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainGetBb(pSwapchain); 1757 PVBOXWDDMDISP_RESOURCE pRc = pRt->pAlloc->pRc; 1758 pParams->BackBufferWidth = pRt->pAlloc->SurfDesc.width; 1759 pParams->BackBufferHeight = pRt->pAlloc->SurfDesc.height; 1760 pParams->BackBufferFormat = vboxDDI2D3DFormat(pRt->pAlloc->SurfDesc.format); 1761 pParams->BackBufferCount = pSwapchain->cRTs - 1; 1762 pParams->MultiSampleType = vboxDDI2D3DMultiSampleType(pRc->RcDesc.enmMultisampleType); 1763 pParams->MultiSampleQuality = pRc->RcDesc.MultisampleQuality; 1764 if (pRc->RcDesc.fFlags.DiscardRenderTarget) 1765 pParams->SwapEffect = D3DSWAPEFFECT_DISCARD; 1766 } 1767 1768 static HRESULT vboxWddmSwapchainChkCreateIf(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain) 1769 { 1770 if (!pSwapchain->fFlags.bChanged && pSwapchain->pSwapChainIf) 1771 return S_OK; 1772 /* preserve the old one */ 1773 IDirect3DSwapChain9 * pOldIf = pSwapchain->pSwapChainIf; 1774 HWND hOldWnd = pSwapchain->hWnd; 1775 /* first create the new one */ 1776 D3DPRESENT_PARAMETERS Params; 1777 vboxWddmSwapchainFillParams(pSwapchain, &Params); 1778 IDirect3DSwapChain9 * pNewIf; 1779 /// 1780 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter; 1781 UINT cSurfs = pSwapchain->cRTs; 1782 HRESULT hr; 1783 HWND hWnd = NULL; 1784 IDirect3DDevice9 *pDevice9If = NULL; 1785 hr = VBoxDispWndCreate(pAdapter, Params.BackBufferWidth, Params.BackBufferHeight, &hWnd); 1786 Assert(hr == S_OK); 1787 if (hr == S_OK) 1788 { 1789 pSwapchain->hWnd = hWnd; 1790 DWORD fFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING; 1791 if (pDevice->fFlags.AllowMultithreading) 1792 fFlags |= D3DCREATE_MULTITHREADED; 1793 1794 Params.hDeviceWindow = hWnd; 1795 /* @todo: it seems there should be a way to detect this correctly since 1796 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */ 1797 Params.Windowed = TRUE; 1798 // params.EnableAutoDepthStencil = FALSE; 1799 // params.AutoDepthStencilFormat = D3DFMT_UNKNOWN; 1800 // params.Flags; 1801 // params.FullScreen_RefreshRateInHz; 1802 // params.FullScreen_PresentationInterval; 1803 if (!pDevice->pDevice9If) 1804 { 1805 hr = pAdapter->pD3D9If->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, fFlags, &Params, &pDevice9If); 1806 Assert(hr == S_OK); 1807 if (hr == S_OK) 1808 { 1809 pDevice->pDevice9If = pDevice9If; 1810 hr = pDevice9If->GetSwapChain(0, &pNewIf); 1811 Assert(hr == S_OK); 1812 if (hr == S_OK) 1813 { 1814 Assert(pNewIf); 1815 } 1816 else 1817 { 1818 pDevice9If->Release(); 1819 } 1820 } 1821 } 1822 else 1823 { 1824 pDevice9If = pDevice->pDevice9If; 1825 hr = pDevice->pDevice9If->CreateAdditionalSwapChain(&Params, &pNewIf); 1826 Assert(hr == S_OK); 1827 if (hr == S_OK) 1828 { 1829 Assert(pNewIf); 1830 } 1831 } 1832 1833 if (hr == S_OK) 1834 { 1835 Assert(pNewIf); 1836 pSwapchain->pSwapChainIf = pNewIf; 1837 #ifndef VBOXWDDM_WITH_VISIBLE_FB 1838 if (!pSwapchain->pRenderTargetFbCopy) 1839 { 1840 IDirect3DSurface9* pD3D9Surf; 1841 hr = pDevice9If->CreateRenderTarget( 1842 Params.BackBufferWidth, Params.BackBufferHeight, 1843 Params.BackBufferFormat, 1844 Params.MultiSampleType, 1845 Params.MultiSampleQuality, 1846 TRUE, /*bLockable*/ 1847 &pD3D9Surf, 1848 NULL /* HANDLE* pSharedHandle */ 1849 ); 1850 Assert(hr == S_OK); 1851 if (hr == S_OK) 1852 { 1853 Assert(pD3D9Surf); 1854 pSwapchain->pRenderTargetFbCopy = pD3D9Surf; 1855 } 1856 } 1857 #endif 1858 1859 if (hr == S_OK) 1860 { 1861 for (UINT i = 0; i < cSurfs; ++i) 1862 { 1863 PVBOXWDDMDISP_RENDERTGT pRt = &pSwapchain->aRTs[i]; 1864 pRt->pAlloc->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE; 1865 } 1866 1867 hr = vboxWddmSwapchainSynch(pDevice, pSwapchain); 1868 Assert(hr == S_OK); 1869 if (hr == S_OK) 1870 { 1871 for (UINT i = 0; i < cSurfs; ++i) 1872 { 1873 PVBOXWDDMDISP_RENDERTGT pRt = &pSwapchain->aRTs[i]; 1874 hr = vboxWddmSurfSynchMem(pRt->pAlloc->pRc, pRt->pAlloc); 1875 Assert(hr == S_OK); 1876 if (hr != S_OK) 1877 { 1878 break; 1879 } 1880 } 1881 1882 Assert(hr == S_OK); 1883 if (hr == S_OK) 1884 { 1885 Assert(pSwapchain->fFlags.Value == 2); /* bInited */ 1886 if (pOldIf) 1887 { 1888 Assert(hOldWnd); 1889 pOldIf->Release(); 1890 VBoxDispWndDestroy(pAdapter, hOldWnd); 1891 } 1892 else 1893 { 1894 Assert(!hOldWnd); 1895 } 1896 return S_OK; 1897 } 1898 } 1899 } 1900 pNewIf->Release(); 1901 pSwapchain->pSwapChainIf = pOldIf; 1902 } 1903 1904 Assert(hr != S_OK); 1905 1906 HRESULT tmpHr = VBoxDispWndDestroy(pAdapter, hWnd); 1907 Assert(tmpHr == S_OK); 1908 pSwapchain->hWnd = hOldWnd; 1909 } 1910 1911 return hr; 1912 } 1913 1914 static HRESULT vboxWddmSwapchainCreateIfForRc(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc, PVBOXWDDMDISP_SWAPCHAIN *ppSwapchain) 1915 { 1916 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainCreateForRc(pDevice, pRc); 1917 Assert(pSwapchain); 1918 *ppSwapchain = NULL; 1919 if (pSwapchain) 1920 { 1921 HRESULT hr = vboxWddmSwapchainChkCreateIf(pDevice, pSwapchain); 1922 Assert(hr == S_OK); 1923 if (hr == S_OK) 1924 { 1925 *ppSwapchain = pSwapchain; 1926 } 1927 return hr; 1928 } 1929 return E_OUTOFMEMORY; 1930 } 1931 1932 static HRESULT vboxWddmSwapchainPresentPerform(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain) 1933 { 1934 HRESULT hr = pSwapchain->pSwapChainIf->Present(NULL, NULL, NULL, NULL, 0); 1935 Assert(hr == S_OK); 1936 if (hr == S_OK) 1937 { 1938 vboxWddmSwapchainFlip(pSwapchain); 1939 Assert(pSwapchain->fFlags.Value == 2); /* bInited */ 1940 hr = vboxWddmSwapchainSynch(pDevice, pSwapchain); 1941 Assert(hr == S_OK); 1942 } 1943 return hr; 1944 } 1945 1946 static HRESULT vboxWddmSwapchainPresent(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pBbAlloc) 1947 { 1948 BOOL bChanged = FALSE; 1949 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainFindCreate(pDevice, pBbAlloc); 1950 Assert(pSwapchain); 1951 if (pSwapchain) 1952 { 1953 HRESULT hr = vboxWddmSwapchainChkCreateIf(pDevice, pSwapchain); 1954 Assert(hr == S_OK); 1955 if (hr == S_OK) 1956 { 1957 hr = vboxWddmSwapchainPresentPerform(pDevice, pSwapchain); 1958 Assert(hr == S_OK); 1959 } 1960 return hr; 1961 } 1962 return E_OUTOFMEMORY; 1963 } 1964 1965 #if 0 //def DEBUG 1966 static void vboxWddmDbgRenderTargetUpdateCheckSurface(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, uint32_t iBBuf) 1967 { 1968 IDirect3DSurface9 *pD3D9Surf; 1969 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE); 1970 IDirect3DDevice9 * pDevice9If = pDevice->aScreens[pDevice->iPrimaryScreen].pDevice9If; 1971 HRESULT hr = pDevice9If->GetBackBuffer(0 /*UINT iSwapChain*/, 1972 iBBuf, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf); 1973 Assert(hr == S_OK); 1974 if (hr == S_OK) 1975 { 1976 Assert(pD3D9Surf); 1977 Assert(pD3D9Surf == pAlloc->pD3DIf); 1978 pD3D9Surf->Release(); 1979 } 1980 } 1981 1982 static void vboxWddmDbgRenderTargetCheck(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc, uint32_t iNewRTFB) 1983 { 1984 PVBOXWDDMDISP_ALLOCATION pAlloc; 1985 UINT iBBuf = 0; 1986 Assert(iNewRTFB < pRc->cAllocations); 1987 1988 for (UINT i = 1; i < pRc->cAllocations; ++i, ++iBBuf) 1989 { 1990 UINT iAlloc = (iNewRTFB + i) % pRc->cAllocations; 1991 Assert(iAlloc != iNewRTFB); 1992 pAlloc = &pRc->aAllocations[iAlloc]; 1993 vboxWddmDbgRenderTargetUpdateCheckSurface(pDevice, pAlloc, iBBuf); 1994 } 1995 1996 pAlloc = &pRc->aAllocations[iNewRTFB]; 1997 #ifdef VBOXWDDM_WITH_VISIBLE_FB 1998 vboxWddmDbgRenderTargetUpdateCheckSurface(pDevice, pAlloc, ~0UL /* <- for the frontbuffer */); 1999 #else 2000 Assert((!pAlloc->pD3DIf) == (pRc->cAllocations > 1)); 2001 #endif 2002 2003 for (UINT i = 0; i < pRc->cAllocations; ++i) 2004 { 2005 pAlloc = &pRc->aAllocations[i]; 2006 if (iNewRTFB == i) 2007 { 2008 Assert((!pAlloc->pD3DIf) == (pRc->cAllocations > 1)); 2009 } 2010 2011 for (UINT j = i+1; j < pRc->cAllocations; ++j) 2012 { 2013 PVBOXWDDMDISP_ALLOCATION pAllocJ = &pRc->aAllocations[j]; 2014 Assert(pAlloc->pD3DIf != pAllocJ->pD3DIf); 2015 } 2016 } 2017 } 2018 2019 # define VBOXVDBG_RTGT_STATECHECK(_pDev) (vboxWddmDbgRenderTargetCheck((_pDev), (_pDev)->aScreens[(_pDev)->iPrimaryScreen].pRenderTargetRc, (_pDev)->aScreens[(_pDev)->iPrimaryScreen].iRenderTargetFrontBuf)) 2020 #else 2021 # define VBOXVDBG_RTGT_STATECHECK(_pDev) do{}while(0) 2022 #endif 2023 2024 #if 0 2025 static HRESULT vboxWddmD3DDeviceCreate(PVBOXWDDMDISP_DEVICE pDevice, UINT iScreen, PVBOXWDDMDISP_RESOURCE pRc, D3DPRESENT_PARAMETERS * pParams, BOOL bLockable) 2026 { 2027 UINT cSurfs = pParams->BackBufferCount + 1; 2028 Assert(pRc->cAllocations = cSurfs); 2029 IDirect3DDevice9 *pPrimaryDevice = pDevice->aScreens[pDevice->iPrimaryScreen].pDevice9If; 2030 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[iScreen]; 2031 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter; 2032 HRESULT hr; 2033 HWND hWnd = NULL; 2034 Assert(!pScreen->pDevice9If); 2035 Assert(!pScreen->hWnd); 2036 hr = VBoxDispWndCreate(pAdapter, pParams->BackBufferWidth, pParams->BackBufferHeight, &hWnd); 2037 Assert(hr == S_OK); 2038 if (hr == S_OK) 2039 { 2040 pScreen->hWnd = hWnd; 2041 2042 DWORD fFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING; 2043 if (pDevice->fFlags.AllowMultithreading) 2044 fFlags |= D3DCREATE_MULTITHREADED; 2045 2046 IDirect3DDevice9 *pDevice9If = NULL; 2047 pParams->hDeviceWindow = hWnd; 2048 /* @todo: it seems there should be a way to detect this correctly since 2049 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */ 2050 pParams->Windowed = TRUE; 2051 // params.EnableAutoDepthStencil = FALSE; 2052 // params.AutoDepthStencilFormat = D3DFMT_UNKNOWN; 2053 // params.Flags; 2054 // params.FullScreen_RefreshRateInHz; 2055 // params.FullScreen_PresentationInterval; 2056 hr = pAdapter->pD3D9If->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, fFlags, pParams, &pDevice9If); 2057 Assert(hr == S_OK); 2058 if (hr == S_OK) 2059 { 2060 pScreen->pDevice9If = pDevice9If; 2061 pScreen->pRenderTargetRc = pRc; 2062 ++pDevice->cScreens; 2063 2064 for (UINT i = 0; i < cSurfs; ++i) 2065 { 2066 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i]; 2067 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE; 2068 } 2069 2070 if (pPrimaryDevice) 2071 { 2072 for (UINT i = 0; i < cSurfs; ++i) 2073 { 2074 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i]; 2075 IDirect3DSurface9 *pRt; 2076 IDirect3DSurface9 *pSecondaryOpenedRt; 2077 HANDLE hSharedHandle = NULL; 2078 hr = pPrimaryDevice->CreateRenderTarget( 2079 pParams->BackBufferWidth, pParams->BackBufferHeight, 2080 pParams->BackBufferFormat, 2081 pParams->MultiSampleType, 2082 pParams->MultiSampleQuality, 2083 TRUE, /*BOOL Lockable*/ 2084 &pRt, 2085 &hSharedHandle); 2086 Assert(hr == S_OK); 2087 if (hr == S_OK) 2088 { 2089 Assert(hSharedHandle != NULL); 2090 /* open render target for primary device */ 2091 hr = pDevice9If->CreateRenderTarget( 2092 pParams->BackBufferWidth, pParams->BackBufferHeight, 2093 pParams->BackBufferFormat, 2094 pParams->MultiSampleType, 2095 pParams->MultiSampleQuality, 2096 TRUE, /*BOOL Lockable*/ 2097 &pSecondaryOpenedRt, 2098 &hSharedHandle); 2099 Assert(hr == S_OK); 2100 if (hr == S_OK) 2101 { 2102 pAllocation->pD3DIf = pRt; 2103 pAllocation->pSecondaryOpenedD3DIf = pSecondaryOpenedRt; 2104 pAllocation->hSharedHandle = hSharedHandle; 2105 continue; 2106 } 2107 pRt->Release(); 2108 } 2109 2110 for (UINT j = 0; j < i; ++j) 2111 { 2112 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[j]; 2113 pAlloc->pD3DIf->Release(); 2114 pAlloc->pSecondaryOpenedD3DIf->Release(); 2115 } 2116 2117 break; 2118 } 2119 } 2120 else 2121 { 2122 pDevice->iPrimaryScreen = iScreen; 2123 hr = vboxWddmRenderTargetUpdate(pDevice, pRc, 0); 2124 Assert(hr == S_OK); 2125 } 2126 2127 if (hr == S_OK) 2128 { 2129 for (UINT i = 0; i < cSurfs; ++i) 2130 { 2131 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i]; 2132 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE; 2133 hr = vboxWddmSurfSynchMem(pRc, pAllocation); 2134 Assert(hr == S_OK); 2135 if (hr != S_OK) 2136 { 2137 break; 2138 } 2139 } 2140 2141 #ifndef VBOXWDDM_WITH_VISIBLE_FB 2142 if (!pPrimaryDevice) 2143 { 2144 if (hr == S_OK) 2145 { 2146 IDirect3DSurface9* pD3D9Surf; 2147 hr = pDevice9If->CreateRenderTarget( 2148 pParams->BackBufferWidth, pParams->BackBufferHeight, 2149 pParams->BackBufferFormat, 2150 pParams->MultiSampleType, 2151 pParams->MultiSampleQuality, 2152 bLockable, 2153 &pD3D9Surf, 2154 NULL /* HANDLE* pSharedHandle */ 2155 ); 2156 Assert(hr == S_OK); 2157 if (hr == S_OK) 2158 { 2159 pDevice->pRenderTargetFbCopy = pD3D9Surf; 2160 } 2161 } 2162 } 2163 #endif 2164 2165 if (hr != S_OK) 2166 { 2167 for (UINT i = 0; i < cSurfs; ++i) 2168 { 2169 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i]; 2170 pAllocation->pD3DIf->Release(); 2171 } 2172 } 2173 } 2174 2175 if (hr != S_OK) 2176 { 2177 pDevice9If->Release(); 2178 --pDevice->cScreens; 2179 Assert(pDevice->cScreens < UINT32_MAX/2); 2180 } 2181 } 2182 2183 if (hr != S_OK) 2184 { 2185 HRESULT tmpHr = VBoxDispWndDestroy(pAdapter, pScreen->hWnd); 2186 Assert(tmpHr == S_OK); 2187 } 2188 } 2189 2190 return hr; 2191 } 2192 #endif 2193 static HRESULT vboxWddmD3DDeviceCreateDummy(PVBOXWDDMDISP_DEVICE pDevice) 2194 { 2195 HRESULT hr; 2196 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(2); 2197 Assert(pRc); 2198 if (pRc) 2199 { 2200 pRc->RcDesc.enmFormat = D3DDDIFMT_A8R8G8B8; 2201 pRc->RcDesc.enmMultisampleType = D3DDDIMULTISAMPLE_NONE; 2202 pRc->RcDesc.MultisampleQuality = 0; 2203 for (UINT i = 0 ; i < pRc->cAllocations; ++i) 2204 { 2205 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[i]; 2206 pAlloc->SurfDesc.width = 0x400; 2207 pAlloc->SurfDesc.height = 0x300; 2208 pAlloc->SurfDesc.format = D3DDDIFMT_A8R8G8B8; 2209 } 2210 2211 PVBOXWDDMDISP_SWAPCHAIN pSwapchain; 2212 hr = vboxWddmSwapchainCreateIfForRc(pDevice, pRc, &pSwapchain); 2213 Assert(hr == S_OK); 2214 if (hr != S_OK) 2215 vboxResourceFree(pRc); 2216 } 2217 else 2218 { 2219 hr = E_OUTOFMEMORY; 2220 } 2221 2222 return hr; 2223 } 2224 2225 DECLINLINE(IDirect3DDevice9*) vboxWddmD3DDeviceGet(PVBOXWDDMDISP_DEVICE pDevice) 2226 { 2227 if (pDevice->pDevice9If) 2228 return pDevice->pDevice9If; 2229 HRESULT hr = vboxWddmD3DDeviceCreateDummy(pDevice); 2230 Assert(hr == S_OK); 2231 Assert(pDevice->pDevice9If); 2232 return pDevice->pDevice9If; 2233 } 2234 2235 #if 0 2236 static HRESULT APIENTRY vboxWddmDDevDestroyResource(HANDLE hDevice, HANDLE hResource); 2237 2238 static HRESULT vboxWddmD3DDeviceUpdate(PVBOXWDDMDISP_DEVICE pDevice, UINT iScreen, PVBOXWDDMDISP_RESOURCE pRc, D3DPRESENT_PARAMETERS * pParams, BOOL bLockable) 2239 { 2240 UINT cSurfs = pParams->BackBufferCount + 1; 2241 Assert(pRc->cAllocations = cSurfs); 2242 Assert(iScreen == pDevice->iPrimaryScreen); 2243 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[iScreen]; 2244 PVBOXWDDMDISP_RESOURCE pCurRc = pScreen->pRenderTargetRc; 2245 IDirect3DDevice9Ex *pNewDevice; 2246 HRESULT hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9Update((IDirect3DDevice9Ex*)pScreen->pDevice9If, pParams, &pNewDevice); 2247 Assert(hr == S_OK); 2248 if (hr == S_OK) 2249 { 2250 pScreen->pDevice9If->Release(); 2251 pScreen->pDevice9If = pNewDevice; 2252 pScreen->pRenderTargetRc = pRc; 2253 2254 for (UINT i = 0; i < cSurfs; ++i) 2255 { 2256 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i]; 2257 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE; 2258 } 2259 2260 #ifndef VBOXWDDM_WITH_VISIBLE_FB 2261 if (pDevice->pRenderTargetFbCopy) 2262 { 2263 pDevice->pRenderTargetFbCopy->Release(); 2264 } 2265 IDirect3DSurface9* pD3D9Surf; 2266 hr = pNewDevice->CreateRenderTarget( 2267 pParams->BackBufferWidth, pParams->BackBufferHeight, 2268 pParams->BackBufferFormat, 2269 pParams->MultiSampleType, 2270 pParams->MultiSampleQuality, 2271 bLockable, 2272 &pD3D9Surf, 2273 NULL /* HANDLE* pSharedHandle */ 2274 ); 2275 Assert(hr == S_OK); 2276 if (hr == S_OK) 2277 { 2278 pDevice->pRenderTargetFbCopy = pD3D9Surf; 2279 } 2280 #endif 2281 if (hr == S_OK) 2282 { 2283 hr = vboxWddmRenderTargetUpdate(pDevice, pRc, 0); 2284 Assert(hr == S_OK); 2285 if (hr == S_OK) 2286 { 2287 for (UINT i = 0; i < cSurfs; ++i) 2288 { 2289 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i]; 2290 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE; 2291 hr = vboxWddmSurfSynchMem(pRc, pAllocation); 2292 Assert(hr == S_OK); 2293 if (hr != S_OK) 2294 { 2295 break; 2296 } 2297 } 2298 } 2299 } 2300 } 2301 2302 2303 if (!pCurRc->hResource) 2304 { 2305 HRESULT tmpHr = vboxWddmDDevDestroyResource(pDevice, pCurRc); 2306 Assert(tmpHr == S_OK); 2307 } 2308 2309 return hr; 2310 } 2311 #endif 2312 /******/ 2313 1680 2314 1681 2315 static CRITICAL_SECTION g_VBoxCritSect; … … 3016 3650 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter)) 3017 3651 { 3018 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen]; 3019 3020 Assert(pRc != pScreen->pRenderTargetRc || pScreen->iRenderTargetFrontBuf != pData->SubResourceIndex); 3652 // Assert(pRc != pScreen->pRenderTargetRc || pScreen->iRenderTargetFrontBuf != pData->SubResourceIndex); 3021 3653 3022 3654 if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE) … … 3654 4286 pAllocation->hAllocation = NULL; 3655 4287 pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC; 4288 pAllocation->pRc = pRc; 3656 4289 pAllocation->pvMem = (void*)pSurf->pSysMem; 3657 4290 pAllocation->SurfDesc.pitch = pSurf->SysMemPitch; … … 3903 4536 bIssueCreateResource = true; 3904 4537 Assert(pResource->SurfCount); 3905 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pResource->VidPnSourceId]; 3906 bool bDevAdjusted = pScreen->pRenderTargetRc && pScreen->pRenderTargetRc->hResource; 3907 bool bIsPrimary = !(pDevice->aScreens[pDevice->iPrimaryScreen].pRenderTargetRc 3908 && pDevice->aScreens[pDevice->iPrimaryScreen].pRenderTargetRc->hResource); 3909 if (!bDevAdjusted) 3910 { 3911 D3DPRESENT_PARAMETERS params; 3912 memset(¶ms, 0, sizeof (params)); 3913 params.BackBufferWidth = pResource->pSurfList[0].Width; 3914 params.BackBufferHeight = pResource->pSurfList[0].Height; 3915 params.BackBufferFormat = vboxDDI2D3DFormat(pResource->Format); 3916 Assert(pResource->SurfCount); 3917 params.BackBufferCount = bIsPrimary ? pResource->SurfCount - 1 : 0; 3918 params.MultiSampleType = vboxDDI2D3DMultiSampleType(pResource->MultisampleType); 3919 if (pResource->Flags.DiscardRenderTarget) 3920 params.SwapEffect = D3DSWAPEFFECT_DISCARD; 3921 // params.hDeviceWindow = hWnd; 3922 /* @todo: it seems there should be a way to detect this correctly since 3923 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */ 3924 params.Windowed = TRUE; 3925 // params.EnableAutoDepthStencil = FALSE; 3926 // params.AutoDepthStencilFormat = D3DFMT_UNKNOWN; 3927 // params.Flags; 3928 // params.FullScreen_RefreshRateInHz; 3929 // params.FullScreen_PresentationInterval; 3930 3931 if (!pScreen->pDevice9If) 3932 { 3933 #ifdef VBOXDISP_EARLYCREATEDEVICE 3934 Assert(!bIsPrimary); 3935 #endif 3936 hr = vboxWddmD3DDeviceCreate(pDevice, pResource->VidPnSourceId, pRc, ¶ms, !pResource->Flags.NotLockable /*BOOL bLockable*/); 3937 Assert(hr == S_OK); 3938 } 3939 else 3940 { 3941 Assert(bIsPrimary); 3942 hr = vboxWddmD3DDeviceUpdate(pDevice, pResource->VidPnSourceId, pRc, ¶ms, !pResource->Flags.NotLockable /*BOOL bLockable*/); 3943 Assert(hr == S_OK); 3944 } 4538 if (RTListIsEmpty(&pDevice->SwapchainList)) 4539 { 4540 PVBOXWDDMDISP_SWAPCHAIN pSwapchain; 4541 hr = vboxWddmSwapchainCreateIfForRc(pDevice, pRc, &pSwapchain); 4542 Assert(hr == S_OK); 3945 4543 } 3946 4544 else 3947 4545 { 3948 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];3949 Assert(pScreen->hWnd);3950 Assert(pScreen->pDevice9If);3951 4546 for (UINT i = 0; i < pResource->SurfCount; ++i) 3952 4547 { … … 3954 4549 3955 4550 IDirect3DSurface9* pD3D9Surf; 3956 hr = p Screen->pDevice9If->CreateRenderTarget(pAllocation->SurfDesc.width,4551 hr = pDevice->pDevice9If->CreateRenderTarget(pAllocation->SurfDesc.width, 3957 4552 pAllocation->SurfDesc.height, 3958 4553 vboxDDI2D3DFormat(pResource->Format), … … 3988 4583 else 3989 4584 { 3990 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];3991 Assert(pScreen->hWnd);3992 Assert(pScreen->pDevice9If);4585 // PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen]; 4586 // Assert(pScreen->hWnd); 4587 // Assert(pScreen->pDevice9If); 3993 4588 Assert(0); 3994 4589 } … … 4173 4768 pAlloc->pSecondaryOpenedD3DIf->Release(); 4174 4769 4770 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc); 4771 if (pSwapchain) 4772 { 4773 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainRtForAlloc(pSwapchain, pAlloc); 4774 vboxWddmSwapchainRtRemove(pSwapchain, pRt); 4775 Assert(!vboxWddmSwapchainForAlloc(pAlloc)); 4776 } 4777 4175 4778 EnterCriticalSection(&pDevice->DirtyAllocListLock); 4176 4779 if (pAlloc->DirtyAllocListEntry.pNext) … … 4231 4834 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE); 4232 4835 Assert(pAlloc->hAllocation); 4233 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];4234 Assert(pScreen->hWnd);4235 Assert(pScreen->pDevice9If);4836 // PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId]; 4837 // Assert(pScreen->hWnd); 4838 // Assert(pScreen->pDevice9If); 4236 4839 D3DDDICB_SETDISPLAYMODE DdiDm = {0}; 4237 4840 DdiDm.hPrimaryAllocation = pAlloc->hAllocation; 4238 4841 // DdiDm.PrivateDriverFormatAttribute = 0; 4239 Assert(pScreen->pRenderTargetRc == pRc);4240 Assert(pScreen->iRenderTargetFrontBuf == pData->SubResourceIndex);4842 // Assert(pScreen->pRenderTargetRc == pRc); 4843 // Assert(pScreen->iRenderTargetFrontBuf == pData->SubResourceIndex); 4241 4844 4242 4845 #if 0 … … 4262 4865 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter)) 4263 4866 { 4867 #if 1 4868 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource; 4869 Assert(pRc); 4870 Assert(pRc->cAllocations > pData->SrcSubResourceIndex); 4871 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex]; 4872 hr = vboxWddmSwapchainPresent(pDevice, pAlloc); 4873 Assert(hr == S_OK); 4874 #else 4264 4875 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource; 4265 4876 Assert(pRc); … … 4305 4916 Assert(hr == S_OK); 4306 4917 #endif 4918 #endif 4307 4919 } 4308 4920 #if 0 … … 4310 4922 #endif 4311 4923 { 4312 if (pData->Flags.Flip)4313 {4314 Assert(pData->hSrcResource);4315 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;4316 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];4317 Assert(pScreen->hWnd);4318 Assert(pScreen->pDevice9If);4319 Assert(pScreen->pRenderTargetRc == pRc);4320 Assert(pRc->cAllocations >= 2);4321 Assert(pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);4322 Assert(pRc->RcDesc.fFlags.RenderTarget);4323 uint32_t iNewRTFB = (pScreen->iRenderTargetFrontBuf + 1) % pRc->cAllocations;4324 4325 Assert(pScreen->iRenderTargetFrontBuf != iNewRTFB);4326 Assert(pData->SrcSubResourceIndex == iNewRTFB);4327 4328 vboxWddmRenderTargetUpdate(pDevice, pRc, iNewRTFB);4329 4330 /* assign a new frontbuffer index */4331 pScreen->iRenderTargetFrontBuf = iNewRTFB;4332 4333 VBOXVDBG_RTGT_STATECHECK(pDevice);4334 }4924 // if (pData->Flags.Flip) 4925 // { 4926 // Assert(pData->hSrcResource); 4927 // PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource; 4928 // PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId]; 4929 // Assert(pScreen->hWnd); 4930 // Assert(pScreen->pDevice9If); 4931 // Assert(pScreen->pRenderTargetRc == pRc); 4932 // Assert(pRc->cAllocations >= 2); 4933 // Assert(pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE); 4934 // Assert(pRc->RcDesc.fFlags.RenderTarget); 4935 // uint32_t iNewRTFB = (pScreen->iRenderTargetFrontBuf + 1) % pRc->cAllocations; 4936 // 4937 // Assert(pScreen->iRenderTargetFrontBuf != iNewRTFB); 4938 // Assert(pData->SrcSubResourceIndex == iNewRTFB); 4939 // 4940 // vboxWddmRenderTargetUpdate(pDevice, pRc, iNewRTFB); 4941 // 4942 // /* assign a new frontbuffer index */ 4943 // pScreen->iRenderTargetFrontBuf = iNewRTFB; 4944 // 4945 // VBOXVDBG_RTGT_STATECHECK(pDevice); 4946 // } 4335 4947 D3DDDICB_PRESENT DdiPresent = {0}; 4336 4948 if (pData->hSrcResource) … … 4485 5097 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter)) 4486 5098 { 4487 Assert(pDevice->cScreens);4488 UINT cProcessed = 0;4489 for (UINT i = 0; cProcessed < pDevice->cScreens && i < RT_ELEMENTS(pDevice->aScreens); ++i)4490 {4491 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[i];4492 if (pScreen->pDevice9If)4493 {4494 ++cProcessed;4495 // if (pScreen->pRenderTargetRc->cAllocations == 1)4496 // {4497 // hr = pScreen->pDevice9If->Present(NULL, NULL, NULL, NULL);4498 // Assert(hr == S_OK);4499 // }4500 // else4501 { 4502 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9Flush((IDirect3DDevice9Ex*)p Screen->pDevice9If);5099 // Assert(pDevice->cScreens); 5100 // UINT cProcessed = 0; 5101 // for (UINT i = 0; cProcessed < pDevice->cScreens && i < RT_ELEMENTS(pDevice->aScreens); ++i) 5102 // { 5103 // PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[i]; 5104 // if (pScreen->pDevice9If) 5105 // { 5106 // ++cProcessed; 5107 //// if (pScreen->pRenderTargetRc->cAllocations == 1) 5108 //// { 5109 //// hr = pScreen->pDevice9If->Present(NULL, NULL, NULL, NULL); 5110 //// Assert(hr == S_OK); 5111 //// } 5112 //// else 5113 { 5114 hr = pDevice->pAdapter->D3D.pfnVBoxWineExD3DDev9Flush((IDirect3DDevice9Ex*)pDevice->pDevice9If); 4503 5115 Assert(hr == S_OK); 4504 5116 } 4505 }4506 }5117 // } 5118 // } 4507 5119 4508 5120 vboxWddmNotifySharedChange(pDevice); … … 4839 5451 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice; 4840 5452 Assert(pDevice); 4841 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];5453 // PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen]; 4842 5454 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice); 4843 5455 PVBOXWDDMDISP_RESOURCE pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource; … … 4845 5457 Assert(pDstRc->cAllocations > pData->DstSubResourceIndex); 4846 5458 Assert(pSrcRc->cAllocations > pData->SrcSubResourceIndex); 4847 Assert(pDstRc != pScreen->pRenderTargetRc || pScreen->iRenderTargetFrontBuf != pData->DstSubResourceIndex);4848 5459 HRESULT hr = S_OK; 5460 PVBOXWDDMDISP_ALLOCATION pSrcAlloc = &pSrcRc->aAllocations[pData->SrcSubResourceIndex]; 5461 PVBOXWDDMDISP_ALLOCATION pDstAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex]; 5462 PVBOXWDDMDISP_SWAPCHAIN pSrcSwapchain = vboxWddmSwapchainForAlloc(pSrcAlloc); 5463 PVBOXWDDMDISP_SWAPCHAIN pDstSwapchain = vboxWddmSwapchainForAlloc(pDstAlloc); 5464 Assert(!pDstSwapchain || vboxWddmSwapchainGetFb(pDstSwapchain)->pAlloc != pDstAlloc); 4849 5465 /* try StretchRect */ 4850 5466 IDirect3DSurface9 *pSrcSurfIf = NULL; … … 4858 5474 { 4859 5475 #ifndef VBOXWDDM_WITH_VISIBLE_FB 4860 if (pSrcRc == pScreen->pRenderTargetRc && pScreen->iRenderTargetFrontBuf == pData->SrcSubResourceIndex 4861 && pScreen->pRenderTargetRc->cAllocations > 1) /* work-around wine backbuffer */ 4862 { 4863 PVBOXWDDMDISP_ALLOCATION pSrcAlloc = &pSrcRc->aAllocations[pData->SrcSubResourceIndex]; 4864 PVBOXWDDMDISP_ALLOCATION pDstAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex]; 5476 if (pSrcSwapchain && vboxWddmSwapchainGetFb(pSrcSwapchain)->pAlloc != pSrcAlloc 5477 && vboxWddmSwapchainNumRTs(pSrcSwapchain) > 1) /* work-around wine backbuffer */ 5478 { 4865 5479 // Assert(pSrcAlloc->SurfDesc.width == pDstAlloc->SurfDesc.width); 4866 5480 // Assert(pSrcAlloc->SurfDesc.height == pDstAlloc->SurfDesc.height); … … 4897 5511 #endif 4898 5512 { 4899 pSrcSurfIf = p Device->pRenderTargetFbCopy;5513 pSrcSurfIf = pSrcSwapchain->pRenderTargetFbCopy; 4900 5514 Assert(pSrcSurfIf); 4901 hr = pDevice9If->GetFrontBufferData(0, p Device->pRenderTargetFbCopy);5515 hr = pDevice9If->GetFrontBufferData(0, pSrcSurfIf); 4902 5516 Assert(hr == S_OK); 4903 5517 if (hr == S_OK) … … 5165 5779 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice; 5166 5780 Assert(pDevice); 5167 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];5781 // PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen]; 5168 5782 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice); 5169 5783 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hRenderTarget; 5170 5784 Assert(pRc); 5171 5785 Assert(pData->SubResourceIndex < pRc->cAllocations); 5172 PVBOXWDDMDISP_SCREEN pVisibleScreen = pRc->RcDesc.fFlags.Primary ? &pDevice->aScreens[pRc->RcDesc.VidPnSourceId] : pScreen; 5173 if (pRc == pVisibleScreen->pRenderTargetRc) 5786 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex]; 5787 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc); 5788 // PVBOXWDDMDISP_SCREEN pVisibleScreen = pRc->RcDesc.fFlags.Primary ? &pDevice->aScreens[pRc->RcDesc.VidPnSourceId] : pScreen; 5789 if (pSwapchain) 5174 5790 { 5175 5791 /* backbuffer */ 5176 Assert( pData->SubResourceIndex == ((pVisibleScreen->iRenderTargetFrontBuf + 1) % pVisibleScreen->pRenderTargetRc->cAllocations));5792 Assert(vboxWddmSwapchainGetBb(pSwapchain)->pAlloc == pAlloc); 5177 5793 } 5178 5794 5179 5795 HRESULT hr = S_OK; 5180 5796 IDirect3DSurface9 *pD3D9Surf; 5181 if (p Rc == pScreen->pRenderTargetRc && pRc->cAllocations== 1 && pData->RenderTargetIndex == 0)5797 if (pSwapchain && vboxWddmSwapchainNumRTs(pSwapchain) == 1 && pData->RenderTargetIndex == 0) 5182 5798 { 5183 5799 /* work-around wine double-buffering for the case we have no backbuffers */ … … 5398 6014 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter; 5399 6015 // Assert(!pDevice->cScreens); 5400 #ifndef VBOXWDDM_WITH_VISIBLE_FB 5401 if(pDevice->pRenderTargetFbCopy) 5402 pDevice->pRenderTargetFbCopy->Release(); 5403 #endif 5404 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aScreens); ++i) 5405 { 5406 PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[i]; 5407 if (pScreen->pDevice9If) 5408 { 5409 pScreen->pDevice9If->Release(); 5410 Assert(pScreen->hWnd); 5411 HRESULT tmpHr = VBoxDispWndDestroy(pAdapter, pScreen->hWnd); 5412 Assert(tmpHr == S_OK); 5413 } 5414 } 6016 vboxWddmSwapchainDestroyAll(pDevice); 6017 pDevice->pDevice9If->Release(); 5415 6018 5416 6019 HRESULT hr = vboxDispCmCtxDestroy(pDevice, &pDevice->DefaultContext); … … 5960 6563 do 5961 6564 { 6565 RTListInit(&pDevice->SwapchainList); 5962 6566 Assert(!pCreateData->AllocationListSize 5963 6567 && !pCreateData->PatchLocationListSize); … … 6276 6880 if (bPrimary) 6277 6881 { 6278 PVBOXWDDMDISP_S CREEN pScreen = &pDevice->aScreens[pRc->RcDesc.VidPnSourceId];6279 Assert(p Rc == pScreen->pRenderTargetRc);6280 bFrontBuf = ( iAlloc == pScreen->iRenderTargetFrontBuf);6882 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc); 6883 Assert(pSwapchain); 6884 bFrontBuf = (vboxWddmSwapchainGetBb(pSwapchain)->pAlloc == pAlloc); 6281 6885 } 6282 6886 vboxVDbgDoMpPrintF(pDevice, "%s width(%d), height(%d), format(%d), usage(%s), %s", pPrefix, -
trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.h
r32325 r32425 23 23 24 24 #define VBOXWDDMDISP_MAX_VERTEX_STREAMS 16 25 #define VBOXWDDMDISP_MAX_SWAPCHAIN_SIZE 16 25 26 26 27 #ifdef VBOX_WITH_VIDEOHWACCEL … … 91 92 } VBOXWDDMDISP_INDICES_INFO; 92 93 93 typedef struct VBOXWDDMDISP_SCREEN 94 { 95 IDirect3DDevice9 *pDevice9If; 96 struct VBOXWDDMDISP_RESOURCE *pRenderTargetRc; 97 // struct VBOXWDDMDISP_RESOURCE *pDstSharedRc; 98 uint32_t iRenderTargetFrontBuf; 94 typedef struct VBOXWDDMDISP_RENDERTGT_FLAGS 95 { 96 union 97 { 98 struct 99 { 100 UINT bAdded : 1; 101 UINT bRemoved : 1; 102 UINT Reserved : 30; 103 }; 104 uint32_t Value; 105 }; 106 }VBOXWDDMDISP_RENDERTGT_FLAGS; 107 108 typedef struct VBOXWDDMDISP_RENDERTGT 109 { 110 struct VBOXWDDMDISP_ALLOCATION *pAlloc; 111 UINT cNumFlips; 112 VBOXWDDMDISP_RENDERTGT_FLAGS fFlags; 113 } VBOXWDDMDISP_RENDERTGT, *PVBOXWDDMDISP_RENDERTGT; 114 115 #define VBOXWDDMDISP_INDEX_UNDEFINED (~0) 116 typedef struct VBOXWDDMDISP_SWAPCHAIN_FLAGS 117 { 118 union 119 { 120 struct 121 { 122 UINT bChanged : 1; 123 UINT bInited : 1; 124 UINT Reserved : 30; 125 }; 126 uint32_t Value; 127 }; 128 }VBOXWDDMDISP_SWAPCHAIN_FLAGS; 129 130 typedef struct VBOXWDDMDISP_SWAPCHAIN 131 { 132 RTLISTNODE ListEntry; 133 UINT iBB; /* Backbuffer index */ 134 UINT cRTs; /* Number of render targets in the swapchain */ 135 VBOXWDDMDISP_SWAPCHAIN_FLAGS fFlags; 136 #ifndef VBOXWDDM_WITH_VISIBLE_FB 137 IDirect3DSurface9 *pRenderTargetFbCopy; 138 #endif 139 IDirect3DSwapChain9 *pSwapChainIf; 99 140 HWND hWnd; 100 } VBOXWDDMDISP_SCREEN, *PVBOXWDDMDISP_SCREEN; 141 VBOXWDDMDISP_RENDERTGT aRTs[VBOXWDDMDISP_MAX_SWAPCHAIN_SIZE]; 142 } VBOXWDDMDISP_SWAPCHAIN, *PVBOXWDDMDISP_SWAPCHAIN; 143 144 145 //typedef struct VBOXWDDMDISP_SCREEN 146 //{ 147 // RTLISTNODE SwapchainList; 148 // IDirect3DDevice9 *pDevice9If; 149 //// struct VBOXWDDMDISP_RESOURCE *pDstSharedRc; 150 // uint32_t iRenderTargetFrontBuf; 151 // HWND hWnd; 152 //} VBOXWDDMDISP_SCREEN, *PVBOXWDDMDISP_SCREEN; 101 153 102 154 typedef struct VBOXWDDMDISP_DEVICE … … 104 156 HANDLE hDevice; 105 157 PVBOXWDDMDISP_ADAPTER pAdapter; 158 IDirect3DDevice9 *pDevice9If; 159 RTLISTNODE SwapchainList; 106 160 UINT u32IfVersion; 107 161 UINT uRtVersion; … … 110 164 UINT cbCmdBuffer; 111 165 D3DDDI_CREATEDEVICEFLAGS fFlags; 112 #ifndef VBOXWDDM_WITH_VISIBLE_FB113 IDirect3DSurface9 *pRenderTargetFbCopy;114 #endif115 166 /* number of StreamSources set */ 116 167 UINT cStreamSources; … … 128 179 CRITICAL_SECTION DirtyAllocListLock; 129 180 RTLISTNODE DirtyAllocList; 130 131 UINT iPrimaryScreen;132 UINT cScreens;133 VBOXWDDMDISP_SCREEN aScreens[VBOX_VIDEO_MAX_SCREENS];134 181 } VBOXWDDMDISP_DEVICE, *PVBOXWDDMDISP_DEVICE; 135 182 … … 159 206 D3DKMT_HANDLE hAllocation; 160 207 VBOXWDDM_ALLOC_TYPE enmType; 208 struct VBOXWDDMDISP_RESOURCE *pRc; 161 209 void* pvMem; 162 210 /* object type is defined by enmD3DIfType enum */ … … 169 217 VBOXWDDM_DIRTYREGION DirtyRegion; /* <- dirty region to notify host about */ 170 218 VBOXWDDM_SURFACE_DESC SurfDesc; 219 PVBOXWDDMDISP_SWAPCHAIN pSwapchain; 171 220 } VBOXWDDMDISP_ALLOCATION, *PVBOXWDDMDISP_ALLOCATION; 172 221 … … 199 248 #define VBOXDISP_D3DEV(_p) (_p)->pDevice9If 200 249 #else 201 #define VBOXDISP_D3DEV(_p) vboxWddmD3DDeviceGet Primary(_p)250 #define VBOXDISP_D3DEV(_p) vboxWddmD3DDeviceGet(_p) 202 251 #endif 203 252 -
trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispMp.cpp
r31797 r32425 139 139 VBOXWDDMDISP_CONTEXT *pContext = (VBOXWDDMDISP_CONTEXT*)pHdr->u64UmData; 140 140 PVBOXVIDEOCM_CMD_RECTS_INTERNAL pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)(((uint8_t*)pHdr) + sizeof (VBOXVIDEOCM_CMD_HDR)); 141 UINT iScreen = pContext->pDevice->cScreens == 1 ? pContext->pDevice->iPrimaryScreen : pCmdInternal->VidPnSourceId; 142 PVBOXWDDMDISP_SCREEN pScreen = &pContext->pDevice->aScreens[iScreen]; 143 Assert(pScreen->hWnd); 144 Assert(pScreen->pDevice9If); 145 pRegions->hWnd = pScreen->hWnd; 141 // UINT iScreen = pContext->pDevice->cScreens == 1 ? pContext->pDevice->iPrimaryScreen : pCmdInternal->VidPnSourceId; 142 // PVBOXWDDMDISP_SCREEN pScreen = &pContext->pDevice->aScreens[iScreen]; 143 // Assert(pScreen->hWnd); 144 // Assert(pScreen->pDevice9If); 145 // pRegions->hWnd = pScreen->hWnd; 146 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = RTListNodeGetLast(&pContext->pDevice->SwapchainList, VBOXWDDMDISP_SWAPCHAIN, ListEntry); 147 Assert(pSwapchain); 148 pRegions->hWnd = pSwapchain->hWnd; 146 149 pRegions->pRegions = &pCmdInternal->Cmd; 147 150 }
Note:
See TracChangeset
for help on using the changeset viewer.