1 // 2 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // Display.cpp: Implements the egl::Display class, representing the abstract 8 // display on which graphics are drawn. Implements EGLDisplay. 9 // [EGL 1.4] section 2.1.2 page 3. 10 11 #include "libEGL/Display.h" 12 13 #include <algorithm> 14 #include <vector> 15 16 #include "common/debug.h" 17 18 #include "libEGL/main.h" 19 20 #define REF_RAST 0 // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros 21 #define ENABLE_D3D9EX 1 // Enables use of the IDirect3D9Ex interface, when available 22 23 namespace egl 24 { 25 Display::Display(HDC deviceContext) : mDc(deviceContext) 26 { 27 mD3d9Module = NULL; 28 29 mD3d9 = NULL; 30 mD3d9ex = NULL; 31 mDevice = NULL; 32 mDeviceWindow = NULL; 33 34 mAdapter = D3DADAPTER_DEFAULT; 35 36 #if REF_RAST == 1 || defined(FORCE_REF_RAST) 37 mDeviceType = D3DDEVTYPE_REF; 38 #else 39 mDeviceType = D3DDEVTYPE_HAL; 40 #endif 41 42 mMinSwapInterval = 1; 43 mMaxSwapInterval = 1; 44 } 45 46 Display::~Display() 47 { 48 terminate(); 49 } 50 51 bool Display::initialize() 52 { 53 if (isInitialized()) 54 { 55 return true; 56 } 57 58 mD3d9Module = LoadLibrary(TEXT("d3d9.dll")); 59 if (mD3d9Module == NULL) 60 { 61 terminate(); 62 return false; 63 } 64 65 typedef IDirect3D9* (WINAPI *Direct3DCreate9Func)(UINT); 66 Direct3DCreate9Func Direct3DCreate9Ptr = reinterpret_cast<Direct3DCreate9Func>(GetProcAddress(mD3d9Module, "Direct3DCreate9")); 67 68 if (Direct3DCreate9Ptr == NULL) 69 { 70 terminate(); 71 return false; 72 } 73 74 typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**); 75 Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast<Direct3DCreate9ExFunc>(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex")); 76 77 // Use Direct3D9Ex if available. Among other things, this version is less 78 // inclined to report a lost context, for example when the user switches 79 // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available. 80 if (ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9ex))) 81 { 82 ASSERT(mD3d9ex); 83 mD3d9ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9)); 84 ASSERT(mD3d9); 85 } 86 else 87 { 88 mD3d9 = Direct3DCreate9Ptr(D3D_SDK_VERSION); 89 } 90 91 if (mD3d9) 92 { 93 if (mDc != NULL) 94 { 95 // UNIMPLEMENTED(); // FIXME: Determine which adapter index the device context corresponds to 96 } 97 98 HRESULT result; 99 100 // Give up on getting device caps after about one second. 101 for (int i = 0; i < 10; ++i) 102 { 103 result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps); 104 105 if (SUCCEEDED(result)) 106 { 107 break; 108 } 109 else if (result == D3DERR_NOTAVAILABLE) 110 { 111 Sleep(100); // Give the driver some time to initialize/recover 112 } 113 else if (FAILED(result)) // D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY, D3DERR_INVALIDDEVICE, or another error we can't recover from 114 { 115 terminate(); 116 return error(EGL_BAD_ALLOC, false); 117 } 118 } 119 120 if (mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(2, 0)) 121 { 122 terminate(); 123 return error(EGL_NOT_INITIALIZED, false); 124 } 125 126 // When DirectX9 is running with an older DirectX8 driver, a StretchRect from a regular texture to a render target texture is not supported. 127 // This is required by Texture2D::convertToRenderTarget. 128 if ((mDeviceCaps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) == 0) 129 { 130 terminate(); 131 return error(EGL_NOT_INITIALIZED, false); 132 } 133 134 mMinSwapInterval = 4; 135 mMaxSwapInterval = 0; 136 137 if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) {mMinSwapInterval = std::min(mMinSwapInterval, 0); mMaxSwapInterval = std::max(mMaxSwapInterval, 0);} 138 if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE) {mMinSwapInterval = std::min(mMinSwapInterval, 1); mMaxSwapInterval = std::max(mMaxSwapInterval, 1);} 139 if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) {mMinSwapInterval = std::min(mMinSwapInterval, 2); mMaxSwapInterval = std::max(mMaxSwapInterval, 2);} 140 if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE) {mMinSwapInterval = std::min(mMinSwapInterval, 3); mMaxSwapInterval = std::max(mMaxSwapInterval, 3);} 141 if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR) {mMinSwapInterval = std::min(mMinSwapInterval, 4); mMaxSwapInterval = std::max(mMaxSwapInterval, 4);} 142 143 const D3DFORMAT renderTargetFormats[] = 144 { 145 D3DFMT_A1R5G5B5, 146 // D3DFMT_A2R10G10B10, // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value. 147 D3DFMT_A8R8G8B8, 148 D3DFMT_R5G6B5, 149 // D3DFMT_X1R5G5B5, // Has no compatible OpenGL ES renderbuffer format 150 D3DFMT_X8R8G8B8 151 }; 152 153 const D3DFORMAT depthStencilFormats[] = 154 { 155 // D3DFMT_D16_LOCKABLE, 156 D3DFMT_D32, 157 // D3DFMT_D15S1, 158 D3DFMT_D24S8, 159 D3DFMT_D24X8, 160 // D3DFMT_D24X4S4, 161 D3DFMT_D16, 162 // D3DFMT_D32F_LOCKABLE, 163 // D3DFMT_D24FS8 164 }; 165 166 D3DDISPLAYMODE currentDisplayMode; 167 mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); 168 169 ConfigSet configSet; 170 171 for (int formatIndex = 0; formatIndex < sizeof(renderTargetFormats) / sizeof(D3DFORMAT); formatIndex++) 172 { 173 D3DFORMAT renderTargetFormat = renderTargetFormats[formatIndex]; 174 175 HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat); 176 177 if (SUCCEEDED(result)) 178 { 179 for (int depthStencilIndex = 0; depthStencilIndex < sizeof(depthStencilFormats) / sizeof(D3DFORMAT); depthStencilIndex++) 180 { 181 D3DFORMAT depthStencilFormat = depthStencilFormats[depthStencilIndex]; 182 HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat); 183 184 if (SUCCEEDED(result)) 185 { 186 HRESULT result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat); 187 188 if (SUCCEEDED(result)) 189 { 190 // FIXME: enumerate multi-sampling 191 192 configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0); 193 } 194 } 195 } 196 } 197 } 198 199 // Give the sorted configs a unique ID and store them internally 200 EGLint index = 1; 201 for (ConfigSet::Iterator config = configSet.mSet.begin(); config != configSet.mSet.end(); config++) 202 { 203 Config configuration = *config; 204 configuration.mConfigID = index; 205 index++; 206 207 mConfigSet.mSet.insert(configuration); 208 } 209 } 210 211 if (!isInitialized()) 212 { 213 terminate(); 214 215 return false; 216 } 217 218 static const TCHAR windowName[] = TEXT("AngleHiddenWindow"); 219 static const TCHAR className[] = TEXT("STATIC"); 220 221 mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL); 222 223 return true; 224 } 225 226 void Display::terminate() 227 { 228 while (!mSurfaceSet.empty()) 229 { 230 destroySurface(*mSurfaceSet.begin()); 231 } 232 233 while (!mContextSet.empty()) 234 { 235 destroyContext(*mContextSet.begin()); 236 } 237 238 if (mDevice) 239 { 240 // If the device is lost, reset it first to prevent leaving the driver in an unstable state 241 if (FAILED(mDevice->TestCooperativeLevel())) 242 { 243 resetDevice(); 244 } 245 246 mDevice->Release(); 247 mDevice = NULL; 248 } 249 250 if (mD3d9) 251 { 252 mD3d9->Release(); 253 mD3d9 = NULL; 254 } 255 256 if (mDeviceWindow) 257 { 258 DestroyWindow(mDeviceWindow); 259 mDeviceWindow = NULL; 260 } 261 262 if (mD3d9ex) 263 { 264 mD3d9ex->Release(); 265 mD3d9ex = NULL; 266 } 267 268 if (mD3d9Module) 269 { 270 FreeLibrary(mD3d9Module); 271 mD3d9Module = NULL; 272 } 273 } 274 275 void Display::startScene() 276 { 277 if (!mSceneStarted) 278 { 279 long result = mDevice->BeginScene(); 280 ASSERT(SUCCEEDED(result)); 281 mSceneStarted = true; 282 } 283 } 284 285 void Display::endScene() 286 { 287 if (mSceneStarted) 288 { 289 long result = mDevice->EndScene(); 290 ASSERT(SUCCEEDED(result)); 291 mSceneStarted = false; 292 } 293 } 294 295 bool Display::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig) 296 { 297 return mConfigSet.getConfigs(configs, attribList, configSize, numConfig); 298 } 299 300 bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value) 301 { 302 const egl::Config *configuration = mConfigSet.get(config); 303 304 switch (attribute) 305 { 306 case EGL_BUFFER_SIZE: *value = configuration->mBufferSize; break; 307 case EGL_ALPHA_SIZE: *value = configuration->mAlphaSize; break; 308 case EGL_BLUE_SIZE: *value = configuration->mBlueSize; break; 309 case EGL_GREEN_SIZE: *value = configuration->mGreenSize; break; 310 case EGL_RED_SIZE: *value = configuration->mRedSize; break; 311 case EGL_DEPTH_SIZE: *value = configuration->mDepthSize; break; 312 case EGL_STENCIL_SIZE: *value = configuration->mStencilSize; break; 313 case EGL_CONFIG_CAVEAT: *value = configuration->mConfigCaveat; break; 314 case EGL_CONFIG_ID: *value = configuration->mConfigID; break; 315 case EGL_LEVEL: *value = configuration->mLevel; break; 316 case EGL_NATIVE_RENDERABLE: *value = configuration->mNativeRenderable; break; 317 case EGL_NATIVE_VISUAL_TYPE: *value = configuration->mNativeVisualType; break; 318 case EGL_SAMPLES: *value = configuration->mSamples; break; 319 case EGL_SAMPLE_BUFFERS: *value = configuration->mSampleBuffers; break; 320 case EGL_SURFACE_TYPE: *value = configuration->mSurfaceType; break; 321 case EGL_TRANSPARENT_TYPE: *value = configuration->mTransparentType; break; 322 case EGL_TRANSPARENT_BLUE_VALUE: *value = configuration->mTransparentBlueValue; break; 323 case EGL_TRANSPARENT_GREEN_VALUE: *value = configuration->mTransparentGreenValue; break; 324 case EGL_TRANSPARENT_RED_VALUE: *value = configuration->mTransparentRedValue; break; 325 case EGL_BIND_TO_TEXTURE_RGB: *value = configuration->mBindToTextureRGB; break; 326 case EGL_BIND_TO_TEXTURE_RGBA: *value = configuration->mBindToTextureRGBA; break; 327 case EGL_MIN_SWAP_INTERVAL: *value = configuration->mMinSwapInterval; break; 328 case EGL_MAX_SWAP_INTERVAL: *value = configuration->mMaxSwapInterval; break; 329 case EGL_LUMINANCE_SIZE: *value = configuration->mLuminanceSize; break; 330 case EGL_ALPHA_MASK_SIZE: *value = configuration->mAlphaMaskSize; break; 331 case EGL_COLOR_BUFFER_TYPE: *value = configuration->mColorBufferType; break; 332 case EGL_RENDERABLE_TYPE: *value = configuration->mRenderableType; break; 333 case EGL_MATCH_NATIVE_PIXMAP: *value = false; UNIMPLEMENTED(); break; 334 case EGL_CONFORMANT: *value = configuration->mConformant; break; 335 default: 336 return false; 337 } 338 339 return true; 340 } 341 342 bool Display::createDevice() 343 { 344 D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters(); 345 DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES; 346 347 HRESULT result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice); 348 349 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST) 350 { 351 return error(EGL_BAD_ALLOC, false); 352 } 353 354 if (FAILED(result)) 355 { 356 result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice); 357 358 if (FAILED(result)) 359 { 360 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_NOTAVAILABLE || result == D3DERR_DEVICELOST); 361 return error(EGL_BAD_ALLOC, false); 362 } 363 } 364 365 // Permanent non-default states 366 mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); 367 368 mSceneStarted = false; 369 370 return true; 371 } 372 373 bool Display::resetDevice() 374 { 375 D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters(); 376 HRESULT result; 377 378 do 379 { 380 Sleep(0); // Give the graphics driver some CPU time 381 382 result = mDevice->Reset(&presentParameters); 383 } 384 while (result == D3DERR_DEVICELOST); 385 386 if (FAILED(result)) 387 { 388 return error(EGL_BAD_ALLOC, false); 389 } 390 391 ASSERT(SUCCEEDED(result)); 392 393 return true; 394 } 395 396 Surface *Display::createWindowSurface(HWND window, EGLConfig config) 397 { 398 const Config *configuration = mConfigSet.get(config); 399 400 Surface *surface = new Surface(this, configuration, window); 401 mSurfaceSet.insert(surface); 402 403 return surface; 404 } 405 406 EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext) 407 { 408 if (!mDevice) 409 { 410 if (!createDevice()) 411 { 412 return NULL; 413 } 414 } 415 else if (FAILED(mDevice->TestCooperativeLevel())) // Lost device 416 { 417 if (!resetDevice()) 418 { 419 return NULL; 420 } 421 422 // Restore any surfaces that may have been lost 423 for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++) 424 { 425 (*surface)->resetSwapChain(); 426 } 427 } 428 429 const egl::Config *config = mConfigSet.get(configHandle); 430 431 gl::Context *context = glCreateContext(config, shareContext); 432 mContextSet.insert(context); 433 434 return context; 435 } 436 437 void Display::destroySurface(egl::Surface *surface) 438 { 439 delete surface; 440 mSurfaceSet.erase(surface); 441 } 442 443 void Display::destroyContext(gl::Context *context) 444 { 445 glDestroyContext(context); 446 mContextSet.erase(context); 447 448 if (mContextSet.empty() && mDevice && FAILED(mDevice->TestCooperativeLevel())) // Last context of a lost device 449 { 450 for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++) 451 { 452 (*surface)->release(); 453 } 454 } 455 } 456 457 bool Display::isInitialized() 458 { 459 return mD3d9 != NULL && mConfigSet.size() > 0; 460 } 461 462 bool Display::isValidConfig(EGLConfig config) 463 { 464 return mConfigSet.get(config) != NULL; 465 } 466 467 bool Display::isValidContext(gl::Context *context) 468 { 469 return mContextSet.find(context) != mContextSet.end(); 470 } 471 472 bool Display::isValidSurface(egl::Surface *surface) 473 { 474 return mSurfaceSet.find(surface) != mSurfaceSet.end(); 475 } 476 477 bool Display::hasExistingWindowSurface(HWND window) 478 { 479 for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++) 480 { 481 if ((*surface)->getWindowHandle() == window) 482 { 483 return true; 484 } 485 } 486 487 return false; 488 } 489 490 EGLint Display::getMinSwapInterval() 491 { 492 return mMinSwapInterval; 493 } 494 495 EGLint Display::getMaxSwapInterval() 496 { 497 return mMaxSwapInterval; 498 } 499 500 IDirect3DDevice9 *Display::getDevice() 501 { 502 if (!mDevice) 503 { 504 if (!createDevice()) 505 { 506 return NULL; 507 } 508 } 509 510 return mDevice; 511 } 512 513 D3DCAPS9 Display::getDeviceCaps() 514 { 515 return mDeviceCaps; 516 } 517 518 void Display::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray) 519 { 520 for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++) 521 { 522 HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format, 523 TRUE, (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL); 524 525 multiSampleArray[multiSampleIndex] = SUCCEEDED(result); 526 } 527 } 528 529 bool Display::getCompressedTextureSupport() 530 { 531 D3DDISPLAYMODE currentDisplayMode; 532 mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); 533 534 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)); 535 } 536 537 bool Display::getFloatTextureSupport(bool *filtering, bool *renderable) 538 { 539 D3DDISPLAYMODE currentDisplayMode; 540 mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); 541 542 *filtering = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER, 543 D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) && 544 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER, 545 D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F)); 546 547 *renderable = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, 548 D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F))&& 549 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, 550 D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F)); 551 552 if (!filtering && !renderable) 553 { 554 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, 555 D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) && 556 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, 557 D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F)); 558 } 559 else 560 { 561 return true; 562 } 563 } 564 565 bool Display::getHalfFloatTextureSupport(bool *filtering, bool *renderable) 566 { 567 D3DDISPLAYMODE currentDisplayMode; 568 mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); 569 570 *filtering = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER, 571 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) && 572 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER, 573 D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F)); 574 575 *renderable = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, 576 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) && 577 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, 578 D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F)); 579 580 if (!filtering && !renderable) 581 { 582 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, 583 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) && 584 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, 585 D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F)); 586 } 587 else 588 { 589 return true; 590 } 591 } 592 593 bool Display::getLuminanceTextureSupport() 594 { 595 D3DDISPLAYMODE currentDisplayMode; 596 mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); 597 598 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_L8)); 599 } 600 601 bool Display::getLuminanceAlphaTextureSupport() 602 { 603 D3DDISPLAYMODE currentDisplayMode; 604 mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); 605 606 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8L8)); 607 } 608 609 D3DPOOL Display::getBufferPool(DWORD usage) const 610 { 611 if (mD3d9ex != NULL) 612 { 613 return D3DPOOL_DEFAULT; 614 } 615 else 616 { 617 if (!(usage & D3DUSAGE_DYNAMIC)) 618 { 619 return D3DPOOL_MANAGED; 620 } 621 } 622 623 return D3DPOOL_DEFAULT; 624 } 625 626 bool Display::getEventQuerySupport() 627 { 628 IDirect3DQuery9 *query; 629 HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query); 630 if (SUCCEEDED(result)) 631 { 632 query->Release(); 633 } 634 635 return result != D3DERR_NOTAVAILABLE; 636 } 637 638 D3DPRESENT_PARAMETERS Display::getDefaultPresentParameters() 639 { 640 D3DPRESENT_PARAMETERS presentParameters = {0}; 641 642 // The default swap chain is never actually used. Surface will create a new swap chain with the proper parameters. 643 presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN; 644 presentParameters.BackBufferCount = 1; 645 presentParameters.BackBufferFormat = D3DFMT_UNKNOWN; 646 presentParameters.BackBufferWidth = 1; 647 presentParameters.BackBufferHeight = 1; 648 presentParameters.EnableAutoDepthStencil = FALSE; 649 presentParameters.Flags = 0; 650 presentParameters.hDeviceWindow = mDeviceWindow; 651 presentParameters.MultiSampleQuality = 0; 652 presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; 653 presentParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; 654 presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; 655 presentParameters.Windowed = TRUE; 656 657 return presentParameters; 658 } 659 }