bool StDXManager::checkAqbsSupport(const HWND theWinHandle) { if(!initDxLib()) { return false; } const UINT aD3dAdaptersNb = getAdapterCount(); D3DADAPTER_IDENTIFIER9 anAdapterInfo; for(UINT anAdapterIter = 0; anAdapterIter < aD3dAdaptersNb; ++anAdapterIter) { getAdapterIdentifier(anAdapterIter, 0, &anAdapterInfo); if(anAdapterInfo.VendorId != ST_DX_VENDOR_AMD) { continue; } // setup the present parameters if(getAdapterDisplayMode(anAdapterIter, &myCurrMode) == D3D_OK) { myD3dParams.BackBufferFormat = myCurrMode.Format; myRefreshRate = myCurrMode.RefreshRate; } // create temporary video device myD3dParams.hDeviceWindow = theWinHandle; myD3dDevice = createAqbsTmpDevice(anAdapterIter, theWinHandle, myD3dParams); if(myD3dDevice == NULL) { continue; } // create a surface to be used to communicate with the driver StHandle<StDXAqbsControl> anAqbsControl = new StDXAqbsControl(myD3dDevice); if(!anAqbsControl->isValid()) { myD3dDevice->Release(); myD3dDevice = NULL; return false; } // send the command to the driver using the temporary surface if(!anAqbsControl->enableStereo()) { anAqbsControl.nullify(); myD3dDevice->Release(); myD3dDevice = NULL; return false; } myWithAqbs = true; anAqbsControl.nullify(); myD3dDevice->Release(); myD3dDevice = NULL; return true; } return false; }
IDirect3DDevice9* StDXManager::createAqbsDevice(const UINT theAdapterId, const HWND theWinHandle, const D3DPRESENT_PARAMETERS& theD3dParams) { // first create a temporary windowed device IDirect3DDevice9* aD3dDevTmp = StDXManager::createAqbsTmpDevice(theAdapterId, theWinHandle, theD3dParams); if(aD3dDevTmp == NULL) { return NULL; } // create a surface to be used to communicate with the driver StHandle<StDXAqbsControl> anAqbsControl = new StDXAqbsControl(aD3dDevTmp); if(!anAqbsControl->isValid()) { ST_DEBUG_LOG("StDXManager::createAqbsDevice(), fail to create AQBS sufrace"); aD3dDevTmp->Release(); aD3dDevTmp = NULL; return NULL; } // send the command to the driver using the temporary surface if(!anAqbsControl->enableStereo()) { ST_DEBUG_LOG("StDXManager::createAqbsDevice(), fail to enable stereo via AQBS sufrace"); anAqbsControl.nullify(); aD3dDevTmp->Release(); aD3dDevTmp = NULL; return NULL; } myWithAqbs = true; // see what stereo modes are available ATIDX9GETDISPLAYMODES aDispModeParams; stMemSet(&aDispModeParams, 0, sizeof(ATIDX9GETDISPLAYMODES)); // send stereo command to get the number of available stereo modes. if(!anAqbsControl->sendCommand(ATI_STEREO_GETDISPLAYMODES, (BYTE* )&aDispModeParams, sizeof(ATIDX9GETDISPLAYMODES))) { ST_DEBUG_LOG("StDXManager::createAqbsDevice(), fail to enumerate stereo modes via AQBS sufrace"); anAqbsControl.nullify(); aD3dDevTmp->Release(); aD3dDevTmp = NULL; return NULL; } if(aDispModeParams.dwNumModes != 0) { // allocating memory to get the list of modes. aDispModeParams.pStereoModes = new D3DDISPLAYMODE[aDispModeParams.dwNumModes]; // send stereo command to get the list of stereo modes if(!anAqbsControl->sendCommand(ATI_STEREO_GETDISPLAYMODES, (BYTE* )&aDispModeParams, sizeof(ATIDX9GETDISPLAYMODES))) { ST_DEBUG_LOG("StDXManager::createAqbsDevice(), fail to retrieve stereo modes via AQBS sufrace"); anAqbsControl.nullify(); aD3dDevTmp->Release(); aD3dDevTmp = NULL; delete[] aDispModeParams.pStereoModes; return NULL; } } anAqbsControl.nullify(); int aResFormatMatch = -1; ///ST_DEBUG_LOG(" DX CUDD " + printDisplayFormat(theD3dParams)); ///ST_DEBUG_LOG(" DX CURR " + printDisplayFormat(myCurrMode)); for(int aDispModeIter = int(aDispModeParams.dwNumModes - 1); aDispModeIter >= 0; --aDispModeIter) { const D3DDISPLAYMODE& aDispMode = aDispModeParams.pStereoModes[aDispModeIter]; ///ST_DEBUG_LOG(" DX ST " + printDisplayFormat(aDispMode)); if(aDispMode.Width != theD3dParams.BackBufferWidth || aDispMode.Height != theD3dParams.BackBufferHeight || aDispMode.Format != theD3dParams.BackBufferFormat) { continue; } aResFormatMatch = aDispModeIter; break; } if(aResFormatMatch < 0) { ST_DEBUG_LOG("StDXManager::createAqbsDevice(), stereo display format doesn't found"); aD3dDevTmp->Release(); aD3dDevTmp = NULL; delete[] aDispModeParams.pStereoModes; return NULL; } int aRefreshMatch = -1; UINT aRefreshMax = 0; for(int aDispModeIter = aResFormatMatch; aDispModeIter >= 0; --aDispModeIter) { const D3DDISPLAYMODE& aDispMode = aDispModeParams.pStereoModes[aDispModeIter]; ST_DEBUG_LOG(" DX ST " + printDisplayFormat(aDispMode)); if(aDispMode.Width != theD3dParams.BackBufferWidth || aDispMode.Height != theD3dParams.BackBufferHeight || aDispMode.Format != theD3dParams.BackBufferFormat) { continue; } if(aDispMode.RefreshRate == myRefreshRate) { aRefreshMatch = aDispModeIter; // found a match with the current refresh break; } else if(aDispMode.RefreshRate > aRefreshMax) { aRefreshMax = aDispMode.RefreshRate; aRefreshMatch = aDispModeIter; } } ST_DEBUG_LOG(" DXSSS " + printDisplayFormat(aDispModeParams.pStereoModes[aRefreshMatch])); // a valid multisample value other then 0 or 1 must be set for stereo (ex 2) D3DPRESENT_PARAMETERS aD3dParams = theD3dParams; aD3dParams.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES; aD3dParams.Flags = 0; // can't lock the back buffer aD3dParams.EnableAutoDepthStencil = FALSE; // need to create a special depth buffer aD3dParams.FullScreen_RefreshRateInHz = aDispModeParams.pStereoModes[aRefreshMatch].RefreshRate; aD3dParams.BackBufferFormat = aDispModeParams.pStereoModes[aRefreshMatch].Format; myRefreshRate = aDispModeParams.pStereoModes[aRefreshMatch].RefreshRate; delete[] aDispModeParams.pStereoModes; // override original parameters myD3dParams = aD3dParams; return aD3dDevTmp; }