blob: 946394456ae4c5c3fb1895897936f76a1b42639f [file] [log] [blame]
daniel@transgaming.come979ead2010-09-23 18:03:14 +00001//
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
23namespace egl
24{
25Display::Display(HDC deviceContext) : mDc(deviceContext)
26{
27 mD3d9Module = NULL;
28
29 mD3d9 = NULL;
apatrick@chromium.org9e83b592011-02-10 22:04:34 +000030 mD3d9Ex = NULL;
daniel@transgaming.come979ead2010-09-23 18:03:14 +000031 mDevice = NULL;
apatrick@chromium.org9e83b592011-02-10 22:04:34 +000032 mDeviceEx = NULL;
daniel@transgaming.come979ead2010-09-23 18:03:14 +000033 mDeviceWindow = NULL;
34
35 mAdapter = D3DADAPTER_DEFAULT;
36
37 #if REF_RAST == 1 || defined(FORCE_REF_RAST)
38 mDeviceType = D3DDEVTYPE_REF;
39 #else
40 mDeviceType = D3DDEVTYPE_HAL;
41 #endif
42
43 mMinSwapInterval = 1;
44 mMaxSwapInterval = 1;
45}
46
47Display::~Display()
48{
49 terminate();
50}
51
52bool Display::initialize()
53{
54 if (isInitialized())
55 {
56 return true;
57 }
58
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +000059 mD3d9Module = GetModuleHandle(TEXT("d3d9.dll"));
daniel@transgaming.come979ead2010-09-23 18:03:14 +000060 if (mD3d9Module == NULL)
61 {
62 terminate();
63 return false;
64 }
65
daniel@transgaming.come979ead2010-09-23 18:03:14 +000066 typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**);
67 Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast<Direct3DCreate9ExFunc>(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex"));
68
69 // Use Direct3D9Ex if available. Among other things, this version is less
70 // inclined to report a lost context, for example when the user switches
71 // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available.
apatrick@chromium.org9e83b592011-02-10 22:04:34 +000072 if (ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex)))
daniel@transgaming.come979ead2010-09-23 18:03:14 +000073 {
apatrick@chromium.org9e83b592011-02-10 22:04:34 +000074 ASSERT(mD3d9Ex);
75 mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
daniel@transgaming.come979ead2010-09-23 18:03:14 +000076 ASSERT(mD3d9);
77 }
78 else
79 {
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +000080 mD3d9 = Direct3DCreate9(D3D_SDK_VERSION);
daniel@transgaming.come979ead2010-09-23 18:03:14 +000081 }
82
83 if (mD3d9)
84 {
85 if (mDc != NULL)
86 {
87 // UNIMPLEMENTED(); // FIXME: Determine which adapter index the device context corresponds to
88 }
89
90 HRESULT result;
91
apatrick@chromium.org1c768012010-10-07 00:35:24 +000092 // Give up on getting device caps after about one second.
93 for (int i = 0; i < 10; ++i)
daniel@transgaming.come979ead2010-09-23 18:03:14 +000094 {
95 result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps);
apatrick@chromium.org1c768012010-10-07 00:35:24 +000096
97 if (SUCCEEDED(result))
daniel@transgaming.come979ead2010-09-23 18:03:14 +000098 {
apatrick@chromium.org1c768012010-10-07 00:35:24 +000099 break;
100 }
101 else if (result == D3DERR_NOTAVAILABLE)
102 {
103 Sleep(100); // Give the driver some time to initialize/recover
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000104 }
105 else if (FAILED(result)) // D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY, D3DERR_INVALIDDEVICE, or another error we can't recover from
106 {
apatrick@chromium.org1c768012010-10-07 00:35:24 +0000107 terminate();
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000108 return error(EGL_BAD_ALLOC, false);
109 }
110 }
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000111
112 if (mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(2, 0))
113 {
114 terminate();
115 return error(EGL_NOT_INITIALIZED, false);
116 }
117
apatrick@chromium.org1c768012010-10-07 00:35:24 +0000118 // When DirectX9 is running with an older DirectX8 driver, a StretchRect from a regular texture to a render target texture is not supported.
119 // This is required by Texture2D::convertToRenderTarget.
120 if ((mDeviceCaps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) == 0)
121 {
122 terminate();
123 return error(EGL_NOT_INITIALIZED, false);
124 }
125
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000126 mMinSwapInterval = 4;
127 mMaxSwapInterval = 0;
128
129 if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) {mMinSwapInterval = std::min(mMinSwapInterval, 0); mMaxSwapInterval = std::max(mMaxSwapInterval, 0);}
130 if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE) {mMinSwapInterval = std::min(mMinSwapInterval, 1); mMaxSwapInterval = std::max(mMaxSwapInterval, 1);}
131 if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) {mMinSwapInterval = std::min(mMinSwapInterval, 2); mMaxSwapInterval = std::max(mMaxSwapInterval, 2);}
132 if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE) {mMinSwapInterval = std::min(mMinSwapInterval, 3); mMaxSwapInterval = std::max(mMaxSwapInterval, 3);}
133 if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR) {mMinSwapInterval = std::min(mMinSwapInterval, 4); mMaxSwapInterval = std::max(mMaxSwapInterval, 4);}
134
135 const D3DFORMAT renderTargetFormats[] =
136 {
137 D3DFMT_A1R5G5B5,
138 // D3DFMT_A2R10G10B10, // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value.
139 D3DFMT_A8R8G8B8,
140 D3DFMT_R5G6B5,
daniel@transgaming.com73a5db62010-10-15 17:58:13 +0000141 // D3DFMT_X1R5G5B5, // Has no compatible OpenGL ES renderbuffer format
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000142 D3DFMT_X8R8G8B8
143 };
144
145 const D3DFORMAT depthStencilFormats[] =
146 {
147 // D3DFMT_D16_LOCKABLE,
148 D3DFMT_D32,
149 // D3DFMT_D15S1,
150 D3DFMT_D24S8,
151 D3DFMT_D24X8,
152 // D3DFMT_D24X4S4,
153 D3DFMT_D16,
154 // D3DFMT_D32F_LOCKABLE,
155 // D3DFMT_D24FS8
156 };
157
158 D3DDISPLAYMODE currentDisplayMode;
159 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
160
161 ConfigSet configSet;
162
163 for (int formatIndex = 0; formatIndex < sizeof(renderTargetFormats) / sizeof(D3DFORMAT); formatIndex++)
164 {
165 D3DFORMAT renderTargetFormat = renderTargetFormats[formatIndex];
166
167 HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat);
168
169 if (SUCCEEDED(result))
170 {
171 for (int depthStencilIndex = 0; depthStencilIndex < sizeof(depthStencilFormats) / sizeof(D3DFORMAT); depthStencilIndex++)
172 {
173 D3DFORMAT depthStencilFormat = depthStencilFormats[depthStencilIndex];
174 HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat);
175
176 if (SUCCEEDED(result))
177 {
178 HRESULT result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat);
179
180 if (SUCCEEDED(result))
181 {
182 // FIXME: enumerate multi-sampling
183
vladimirv@gmail.com721b7f22011-02-11 00:54:47 +0000184 configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0,
185 mDeviceCaps.MaxTextureWidth, mDeviceCaps.MaxTextureHeight);
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000186 }
187 }
188 }
189 }
190 }
191
192 // Give the sorted configs a unique ID and store them internally
193 EGLint index = 1;
194 for (ConfigSet::Iterator config = configSet.mSet.begin(); config != configSet.mSet.end(); config++)
195 {
196 Config configuration = *config;
197 configuration.mConfigID = index;
198 index++;
199
200 mConfigSet.mSet.insert(configuration);
201 }
202 }
203
204 if (!isInitialized())
205 {
206 terminate();
207
208 return false;
209 }
210
vladimirv@gmail.com721b7f22011-02-11 00:54:47 +0000211 initExtensionString();
212
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000213 static const TCHAR windowName[] = TEXT("AngleHiddenWindow");
214 static const TCHAR className[] = TEXT("STATIC");
215
216 mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
217
218 return true;
219}
220
221void Display::terminate()
222{
223 while (!mSurfaceSet.empty())
224 {
225 destroySurface(*mSurfaceSet.begin());
226 }
227
228 while (!mContextSet.empty())
229 {
230 destroyContext(*mContextSet.begin());
231 }
232
233 if (mDevice)
234 {
235 // If the device is lost, reset it first to prevent leaving the driver in an unstable state
apatrick@chromium.org9e83b592011-02-10 22:04:34 +0000236 if (isDeviceLost())
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000237 {
238 resetDevice();
239 }
240
241 mDevice->Release();
242 mDevice = NULL;
243 }
244
apatrick@chromium.org9e83b592011-02-10 22:04:34 +0000245 if (mDeviceEx)
246 {
247 mDeviceEx->Release();
248 mDeviceEx = NULL;
249 }
250
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000251 if (mD3d9)
252 {
253 mD3d9->Release();
254 mD3d9 = NULL;
255 }
256
257 if (mDeviceWindow)
258 {
259 DestroyWindow(mDeviceWindow);
260 mDeviceWindow = NULL;
261 }
262
apatrick@chromium.org9e83b592011-02-10 22:04:34 +0000263 if (mD3d9Ex)
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000264 {
apatrick@chromium.org9e83b592011-02-10 22:04:34 +0000265 mD3d9Ex->Release();
266 mD3d9Ex = NULL;
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000267 }
268
269 if (mD3d9Module)
270 {
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000271 mD3d9Module = NULL;
272 }
273}
274
275void Display::startScene()
276{
277 if (!mSceneStarted)
278 {
279 long result = mDevice->BeginScene();
280 ASSERT(SUCCEEDED(result));
281 mSceneStarted = true;
282 }
283}
284
285void Display::endScene()
286{
287 if (mSceneStarted)
288 {
289 long result = mDevice->EndScene();
290 ASSERT(SUCCEEDED(result));
291 mSceneStarted = false;
292 }
293}
294
295bool Display::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
296{
297 return mConfigSet.getConfigs(configs, attribList, configSize, numConfig);
298}
299
300bool 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;
vladimirv@gmail.com721b7f22011-02-11 00:54:47 +0000335 case EGL_MAX_PBUFFER_WIDTH: *value = configuration->mMaxPBufferWidth; break;
336 case EGL_MAX_PBUFFER_HEIGHT: *value = configuration->mMaxPBufferHeight; break;
337 case EGL_MAX_PBUFFER_PIXELS: *value = configuration->mMaxPBufferPixels; break;
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000338 default:
339 return false;
340 }
341
342 return true;
343}
344
345bool Display::createDevice()
346{
347 D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
348 DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;
349
350 HRESULT result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice);
351
352 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST)
353 {
354 return error(EGL_BAD_ALLOC, false);
355 }
356
357 if (FAILED(result))
358 {
359 result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice);
360
361 if (FAILED(result))
362 {
363 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_NOTAVAILABLE || result == D3DERR_DEVICELOST);
364 return error(EGL_BAD_ALLOC, false);
365 }
366 }
367
apatrick@chromium.org9e83b592011-02-10 22:04:34 +0000368 if (mD3d9Ex)
369 {
370 result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**) &mDeviceEx);
371 ASSERT(SUCCEEDED(result));
372 }
373
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000374 // Permanent non-default states
375 mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
376
377 mSceneStarted = false;
378
379 return true;
380}
381
382bool Display::resetDevice()
383{
384 D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
385 HRESULT result;
386
387 do
388 {
389 Sleep(0); // Give the graphics driver some CPU time
390
391 result = mDevice->Reset(&presentParameters);
392 }
393 while (result == D3DERR_DEVICELOST);
394
395 if (FAILED(result))
396 {
397 return error(EGL_BAD_ALLOC, false);
398 }
399
400 ASSERT(SUCCEEDED(result));
401
402 return true;
403}
404
405Surface *Display::createWindowSurface(HWND window, EGLConfig config)
406{
407 const Config *configuration = mConfigSet.get(config);
408
409 Surface *surface = new Surface(this, configuration, window);
410 mSurfaceSet.insert(surface);
411
412 return surface;
413}
414
jbauman@chromium.orgae345802011-03-30 22:04:25 +0000415Surface *Display::createOffscreenSurface(int width, int height, EGLConfig config, EGLenum textureFormat, EGLenum textureTarget)
vladimirv@gmail.com721b7f22011-02-11 00:54:47 +0000416{
417 const Config *configuration = mConfigSet.get(config);
418
jbauman@chromium.orgae345802011-03-30 22:04:25 +0000419 Surface *surface = new Surface(this, configuration, width, height, textureFormat, textureTarget);
vladimirv@gmail.com721b7f22011-02-11 00:54:47 +0000420 mSurfaceSet.insert(surface);
421
422 return surface;
423}
424
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000425EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext)
426{
427 if (!mDevice)
428 {
429 if (!createDevice())
430 {
431 return NULL;
432 }
433 }
apatrick@chromium.org9e83b592011-02-10 22:04:34 +0000434 else if (isDeviceLost()) // Lost device
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000435 {
436 if (!resetDevice())
437 {
438 return NULL;
439 }
440
441 // Restore any surfaces that may have been lost
442 for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
443 {
444 (*surface)->resetSwapChain();
445 }
446 }
447
448 const egl::Config *config = mConfigSet.get(configHandle);
449
450 gl::Context *context = glCreateContext(config, shareContext);
451 mContextSet.insert(context);
452
453 return context;
454}
455
456void Display::destroySurface(egl::Surface *surface)
457{
458 delete surface;
459 mSurfaceSet.erase(surface);
460}
461
462void Display::destroyContext(gl::Context *context)
463{
464 glDestroyContext(context);
465 mContextSet.erase(context);
466
apatrick@chromium.org9e83b592011-02-10 22:04:34 +0000467 if (mContextSet.empty() && mDevice && isDeviceLost()) // Last context of a lost device
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000468 {
469 for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
470 {
471 (*surface)->release();
472 }
473 }
474}
475
476bool Display::isInitialized()
477{
478 return mD3d9 != NULL && mConfigSet.size() > 0;
479}
480
481bool Display::isValidConfig(EGLConfig config)
482{
483 return mConfigSet.get(config) != NULL;
484}
485
486bool Display::isValidContext(gl::Context *context)
487{
488 return mContextSet.find(context) != mContextSet.end();
489}
490
491bool Display::isValidSurface(egl::Surface *surface)
492{
493 return mSurfaceSet.find(surface) != mSurfaceSet.end();
494}
495
496bool Display::hasExistingWindowSurface(HWND window)
497{
498 for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
499 {
500 if ((*surface)->getWindowHandle() == window)
501 {
502 return true;
503 }
504 }
505
506 return false;
507}
508
509EGLint Display::getMinSwapInterval()
510{
511 return mMinSwapInterval;
512}
513
514EGLint Display::getMaxSwapInterval()
515{
516 return mMaxSwapInterval;
517}
518
519IDirect3DDevice9 *Display::getDevice()
520{
521 if (!mDevice)
522 {
523 if (!createDevice())
524 {
525 return NULL;
526 }
527 }
528
529 return mDevice;
530}
531
532D3DCAPS9 Display::getDeviceCaps()
533{
534 return mDeviceCaps;
535}
536
apatrick@chromium.org9e83b592011-02-10 22:04:34 +0000537bool Display::isDeviceLost()
538{
539 if (mDeviceEx)
540 {
541 return FAILED(mDeviceEx->CheckDeviceState(NULL));
542 }
543 else
544 {
545 return FAILED(mDevice->TestCooperativeLevel());
546 }
547}
548
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000549void Display::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray)
550{
551 for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++)
552 {
553 HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format,
554 TRUE, (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL);
555
556 multiSampleArray[multiSampleIndex] = SUCCEEDED(result);
557 }
558}
559
560bool Display::getCompressedTextureSupport()
561{
562 D3DDISPLAYMODE currentDisplayMode;
563 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
564
565 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1));
566}
567
568bool Display::getFloatTextureSupport(bool *filtering, bool *renderable)
569{
570 D3DDISPLAYMODE currentDisplayMode;
571 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
572
573 *filtering = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
574 D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
575 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
576 D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
577
578 *renderable = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
579 D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F))&&
580 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
581 D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
582
583 if (!filtering && !renderable)
584 {
585 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
586 D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
587 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
588 D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
589 }
590 else
591 {
592 return true;
593 }
594}
595
596bool Display::getHalfFloatTextureSupport(bool *filtering, bool *renderable)
597{
598 D3DDISPLAYMODE currentDisplayMode;
599 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
600
601 *filtering = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
602 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
603 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
604 D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
605
606 *renderable = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
607 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
608 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
609 D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
610
611 if (!filtering && !renderable)
612 {
613 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
614 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
615 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
616 D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
617 }
618 else
619 {
620 return true;
621 }
622}
623
daniel@transgaming.comed828e52010-10-15 17:57:30 +0000624bool Display::getLuminanceTextureSupport()
625{
626 D3DDISPLAYMODE currentDisplayMode;
627 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
628
629 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_L8));
630}
631
632bool Display::getLuminanceAlphaTextureSupport()
633{
634 D3DDISPLAYMODE currentDisplayMode;
635 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
636
637 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8L8));
638}
639
jbauman@chromium.orgae345802011-03-30 22:04:25 +0000640bool Display::getNonPow2TextureSupport()
641{
642 return !(mDeviceCaps.TextureCaps & (D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_NONPOW2CONDITIONAL));
643}
644
daniel@transgaming.comee04e452011-01-08 05:46:27 +0000645D3DPOOL Display::getBufferPool(DWORD usage) const
daniel@transgaming.com37b141e2011-01-08 05:46:13 +0000646{
apatrick@chromium.org9e83b592011-02-10 22:04:34 +0000647 if (mD3d9Ex != NULL)
daniel@transgaming.comee04e452011-01-08 05:46:27 +0000648 {
649 return D3DPOOL_DEFAULT;
650 }
651 else
652 {
653 if (!(usage & D3DUSAGE_DYNAMIC))
654 {
655 return D3DPOOL_MANAGED;
656 }
657 }
658
659 return D3DPOOL_DEFAULT;
daniel@transgaming.com37b141e2011-01-08 05:46:13 +0000660}
661
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000662bool Display::getEventQuerySupport()
663{
664 IDirect3DQuery9 *query;
665 HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query);
666 if (SUCCEEDED(result))
667 {
668 query->Release();
669 }
670
671 return result != D3DERR_NOTAVAILABLE;
672}
673
674D3DPRESENT_PARAMETERS Display::getDefaultPresentParameters()
675{
676 D3DPRESENT_PARAMETERS presentParameters = {0};
677
678 // The default swap chain is never actually used. Surface will create a new swap chain with the proper parameters.
679 presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
680 presentParameters.BackBufferCount = 1;
681 presentParameters.BackBufferFormat = D3DFMT_UNKNOWN;
682 presentParameters.BackBufferWidth = 1;
683 presentParameters.BackBufferHeight = 1;
684 presentParameters.EnableAutoDepthStencil = FALSE;
685 presentParameters.Flags = 0;
686 presentParameters.hDeviceWindow = mDeviceWindow;
687 presentParameters.MultiSampleQuality = 0;
688 presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
689 presentParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
690 presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
691 presentParameters.Windowed = TRUE;
692
693 return presentParameters;
694}
vladimirv@gmail.com721b7f22011-02-11 00:54:47 +0000695
696void Display::initExtensionString()
697{
698 mExtensionString += "EGL_ANGLE_query_surface_pointer ";
699
700 if (isD3d9ExDevice()) {
701 mExtensionString += "EGL_ANGLE_surface_d3d_texture_2d_share_handle ";
702 }
703
704 std::string::size_type end = mExtensionString.find_last_not_of(' ');
705 if (end != std::string::npos)
706 {
707 mExtensionString.resize(end+1);
708 }
709}
710
711const char *Display::getExtensionString() const
712{
713 return mExtensionString.c_str();
714}
715
716}