bool Surface::initialize() { ASSERT(!mSwapChain && !mOffscreenTexture && !mDepthStencil); if (!resetSwapChain()) return false; // Modify present parameters for this window, if we are composited, // to minimize the amount of queuing done by DWM between our calls to // present and the actual screen. if (mWindow && (getComparableOSVersion() >= versionWindowsVista)) { BOOL isComposited; HRESULT result = DwmIsCompositionEnabled(&isComposited); if (SUCCEEDED(result) && isComposited) { DWM_PRESENT_PARAMETERS presentParams; memset(&presentParams, 0, sizeof(presentParams)); presentParams.cbSize = sizeof(DWM_PRESENT_PARAMETERS); presentParams.cBuffer = 2; result = DwmSetPresentParameters(mWindow, &presentParams); if (FAILED(result)) ERR("Unable to set present parameters: 0x%08X", result); } } return true; }
bool Display::initialize() { if (isInitialized()) { return true; } if (mSoftwareDevice) { mD3d9Module = GetModuleHandle(TEXT("swiftshader_d3d9.dll")); } else { mD3d9Module = GetModuleHandle(TEXT("d3d9.dll")); } if (mD3d9Module == NULL) { terminate(); return false; } typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**); Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast<Direct3DCreate9ExFunc>(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex")); #if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES) // Find a D3DCompiler module that had already been loaded based on a predefined list of versions. static TCHAR* d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES; for (int i = 0; i < sizeof(d3dCompilerNames) / sizeof(*d3dCompilerNames); ++i) { if (GetModuleHandleEx(0, d3dCompilerNames[i], &mD3dCompilerModule)) { break; } } #else // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with. mD3dCompilerModule = LoadLibrary(D3DCOMPILER_DLL); #endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES if (!mD3dCompilerModule) { terminate(); return false; } mD3DCompileFunc = reinterpret_cast<D3DCompileFunc>(GetProcAddress(mD3dCompilerModule, "D3DCompile")); ASSERT(mD3DCompileFunc); // Use Direct3D9Ex if available. Among other things, this version is less // inclined to report a lost context, for example when the user switches // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available. if (ANGLE_ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) { ASSERT(mD3d9Ex); mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9)); ASSERT(mD3d9); } else { mD3d9 = Direct3DCreate9(D3D_SDK_VERSION); } if (mD3d9) { if (mDc != NULL) { // UNIMPLEMENTED(); // FIXME: Determine which adapter index the device context corresponds to } HRESULT result; // Give up on getting device caps after about one second. for (int i = 0; i < 10; ++i) { result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps); if (SUCCEEDED(result)) { break; } else if (result == D3DERR_NOTAVAILABLE) { Sleep(100); // Give the driver some time to initialize/recover } else if (FAILED(result)) // D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY, D3DERR_INVALIDDEVICE, or another error we can't recover from { terminate(); return error(EGL_BAD_ALLOC, false); } } if (mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(2, 0)) { terminate(); return error(EGL_NOT_INITIALIZED, false); } // When DirectX9 is running with an older DirectX8 driver, a StretchRect from a regular texture to a render target texture is not supported. // This is required by Texture2D::convertToRenderTarget. if ((mDeviceCaps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) == 0) { terminate(); return error(EGL_NOT_INITIALIZED, false); } mMinSwapInterval = 4; mMaxSwapInterval = 0; if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) { mMinSwapInterval = std::min(mMinSwapInterval, 0); mMaxSwapInterval = std::max(mMaxSwapInterval, 0); } if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE) { mMinSwapInterval = std::min(mMinSwapInterval, 1); mMaxSwapInterval = std::max(mMaxSwapInterval, 1); } if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) { mMinSwapInterval = std::min(mMinSwapInterval, 2); mMaxSwapInterval = std::max(mMaxSwapInterval, 2); } if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE) { mMinSwapInterval = std::min(mMinSwapInterval, 3); mMaxSwapInterval = std::max(mMaxSwapInterval, 3); } if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR) { mMinSwapInterval = std::min(mMinSwapInterval, 4); mMaxSwapInterval = std::max(mMaxSwapInterval, 4); } mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier); // ATI cards on XP have problems with non-power-of-two textures. mSupportsNonPower2Textures = !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) && !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) && !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) && !(getComparableOSVersion() < versionWindowsVista && mAdapterIdentifier.VendorId == VENDOR_ID_AMD); const D3DFORMAT renderTargetFormats[] = { D3DFMT_A1R5G5B5, // D3DFMT_A2R10G10B10, // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value. D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, // D3DFMT_X1R5G5B5, // Has no compatible OpenGL ES renderbuffer format D3DFMT_X8R8G8B8 }; const D3DFORMAT depthStencilFormats[] = { D3DFMT_UNKNOWN, // D3DFMT_D16_LOCKABLE, D3DFMT_D32, // D3DFMT_D15S1, D3DFMT_D24S8, D3DFMT_D24X8, // D3DFMT_D24X4S4, D3DFMT_D16, // D3DFMT_D32F_LOCKABLE, // D3DFMT_D24FS8 }; D3DDISPLAYMODE currentDisplayMode; mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); ConfigSet configSet; for (unsigned int formatIndex = 0; formatIndex < sizeof(renderTargetFormats) / sizeof(D3DFORMAT); formatIndex++) { D3DFORMAT renderTargetFormat = renderTargetFormats[formatIndex]; HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat); if (SUCCEEDED(result)) { for (unsigned int depthStencilIndex = 0; depthStencilIndex < sizeof(depthStencilFormats) / sizeof(D3DFORMAT); depthStencilIndex++) { D3DFORMAT depthStencilFormat = depthStencilFormats[depthStencilIndex]; HRESULT result = D3D_OK; if(depthStencilFormat != D3DFMT_UNKNOWN) { result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat); } if (SUCCEEDED(result)) { if(depthStencilFormat != D3DFMT_UNKNOWN) { result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat); } if (SUCCEEDED(result)) { // FIXME: enumerate multi-sampling configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0, mDeviceCaps.MaxTextureWidth, mDeviceCaps.MaxTextureHeight); } } } } } // Give the sorted configs a unique ID and store them internally EGLint index = 1; for (ConfigSet::Iterator config = configSet.mSet.begin(); config != configSet.mSet.end(); config++) { Config configuration = *config; configuration.mConfigID = index; index++; mConfigSet.mSet.insert(configuration); } } if (!isInitialized()) { terminate(); return false; } initExtensionString(); static const TCHAR windowName[] = TEXT("AngleHiddenWindow"); static const TCHAR className[] = TEXT("STATIC"); mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL); if (!createDevice()) { terminate(); return false; } mVertexShaderCache.initialize(mDevice); mPixelShaderCache.initialize(mDevice); return true; }