blob: 4673e734e66ec3d2f5d9ea47c6d6d018d6d21ccb [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
184 configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0);
185 }
186 }
187 }
188 }
189 }
190
191 // Give the sorted configs a unique ID and store them internally
192 EGLint index = 1;
193 for (ConfigSet::Iterator config = configSet.mSet.begin(); config != configSet.mSet.end(); config++)
194 {
195 Config configuration = *config;
196 configuration.mConfigID = index;
197 index++;
198
199 mConfigSet.mSet.insert(configuration);
200 }
201 }
202
203 if (!isInitialized())
204 {
205 terminate();
206
207 return false;
208 }
209
210 static const TCHAR windowName[] = TEXT("AngleHiddenWindow");
211 static const TCHAR className[] = TEXT("STATIC");
212
213 mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
214
215 return true;
216}
217
218void Display::terminate()
219{
220 while (!mSurfaceSet.empty())
221 {
222 destroySurface(*mSurfaceSet.begin());
223 }
224
225 while (!mContextSet.empty())
226 {
227 destroyContext(*mContextSet.begin());
228 }
229
230 if (mDevice)
231 {
232 // 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 +0000233 if (isDeviceLost())
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000234 {
235 resetDevice();
236 }
237
238 mDevice->Release();
239 mDevice = NULL;
240 }
241
apatrick@chromium.org9e83b592011-02-10 22:04:34 +0000242 if (mDeviceEx)
243 {
244 mDeviceEx->Release();
245 mDeviceEx = NULL;
246 }
247
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000248 if (mD3d9)
249 {
250 mD3d9->Release();
251 mD3d9 = NULL;
252 }
253
254 if (mDeviceWindow)
255 {
256 DestroyWindow(mDeviceWindow);
257 mDeviceWindow = NULL;
258 }
259
apatrick@chromium.org9e83b592011-02-10 22:04:34 +0000260 if (mD3d9Ex)
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000261 {
apatrick@chromium.org9e83b592011-02-10 22:04:34 +0000262 mD3d9Ex->Release();
263 mD3d9Ex = NULL;
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000264 }
265
266 if (mD3d9Module)
267 {
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000268 mD3d9Module = NULL;
269 }
270}
271
272void Display::startScene()
273{
274 if (!mSceneStarted)
275 {
276 long result = mDevice->BeginScene();
277 ASSERT(SUCCEEDED(result));
278 mSceneStarted = true;
279 }
280}
281
282void Display::endScene()
283{
284 if (mSceneStarted)
285 {
286 long result = mDevice->EndScene();
287 ASSERT(SUCCEEDED(result));
288 mSceneStarted = false;
289 }
290}
291
292bool Display::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
293{
294 return mConfigSet.getConfigs(configs, attribList, configSize, numConfig);
295}
296
297bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
298{
299 const egl::Config *configuration = mConfigSet.get(config);
300
301 switch (attribute)
302 {
303 case EGL_BUFFER_SIZE: *value = configuration->mBufferSize; break;
304 case EGL_ALPHA_SIZE: *value = configuration->mAlphaSize; break;
305 case EGL_BLUE_SIZE: *value = configuration->mBlueSize; break;
306 case EGL_GREEN_SIZE: *value = configuration->mGreenSize; break;
307 case EGL_RED_SIZE: *value = configuration->mRedSize; break;
308 case EGL_DEPTH_SIZE: *value = configuration->mDepthSize; break;
309 case EGL_STENCIL_SIZE: *value = configuration->mStencilSize; break;
310 case EGL_CONFIG_CAVEAT: *value = configuration->mConfigCaveat; break;
311 case EGL_CONFIG_ID: *value = configuration->mConfigID; break;
312 case EGL_LEVEL: *value = configuration->mLevel; break;
313 case EGL_NATIVE_RENDERABLE: *value = configuration->mNativeRenderable; break;
314 case EGL_NATIVE_VISUAL_TYPE: *value = configuration->mNativeVisualType; break;
315 case EGL_SAMPLES: *value = configuration->mSamples; break;
316 case EGL_SAMPLE_BUFFERS: *value = configuration->mSampleBuffers; break;
317 case EGL_SURFACE_TYPE: *value = configuration->mSurfaceType; break;
318 case EGL_TRANSPARENT_TYPE: *value = configuration->mTransparentType; break;
319 case EGL_TRANSPARENT_BLUE_VALUE: *value = configuration->mTransparentBlueValue; break;
320 case EGL_TRANSPARENT_GREEN_VALUE: *value = configuration->mTransparentGreenValue; break;
321 case EGL_TRANSPARENT_RED_VALUE: *value = configuration->mTransparentRedValue; break;
322 case EGL_BIND_TO_TEXTURE_RGB: *value = configuration->mBindToTextureRGB; break;
323 case EGL_BIND_TO_TEXTURE_RGBA: *value = configuration->mBindToTextureRGBA; break;
324 case EGL_MIN_SWAP_INTERVAL: *value = configuration->mMinSwapInterval; break;
325 case EGL_MAX_SWAP_INTERVAL: *value = configuration->mMaxSwapInterval; break;
326 case EGL_LUMINANCE_SIZE: *value = configuration->mLuminanceSize; break;
327 case EGL_ALPHA_MASK_SIZE: *value = configuration->mAlphaMaskSize; break;
328 case EGL_COLOR_BUFFER_TYPE: *value = configuration->mColorBufferType; break;
329 case EGL_RENDERABLE_TYPE: *value = configuration->mRenderableType; break;
330 case EGL_MATCH_NATIVE_PIXMAP: *value = false; UNIMPLEMENTED(); break;
331 case EGL_CONFORMANT: *value = configuration->mConformant; break;
332 default:
333 return false;
334 }
335
336 return true;
337}
338
339bool Display::createDevice()
340{
341 D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
342 DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;
343
344 HRESULT result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice);
345
346 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST)
347 {
348 return error(EGL_BAD_ALLOC, false);
349 }
350
351 if (FAILED(result))
352 {
353 result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice);
354
355 if (FAILED(result))
356 {
357 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_NOTAVAILABLE || result == D3DERR_DEVICELOST);
358 return error(EGL_BAD_ALLOC, false);
359 }
360 }
361
apatrick@chromium.org9e83b592011-02-10 22:04:34 +0000362 if (mD3d9Ex)
363 {
364 result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**) &mDeviceEx);
365 ASSERT(SUCCEEDED(result));
366 }
367
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000368 // Permanent non-default states
369 mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
370
371 mSceneStarted = false;
372
373 return true;
374}
375
376bool Display::resetDevice()
377{
378 D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
379 HRESULT result;
380
381 do
382 {
383 Sleep(0); // Give the graphics driver some CPU time
384
385 result = mDevice->Reset(&presentParameters);
386 }
387 while (result == D3DERR_DEVICELOST);
388
389 if (FAILED(result))
390 {
391 return error(EGL_BAD_ALLOC, false);
392 }
393
394 ASSERT(SUCCEEDED(result));
395
396 return true;
397}
398
399Surface *Display::createWindowSurface(HWND window, EGLConfig config)
400{
401 const Config *configuration = mConfigSet.get(config);
402
403 Surface *surface = new Surface(this, configuration, window);
404 mSurfaceSet.insert(surface);
405
406 return surface;
407}
408
409EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext)
410{
411 if (!mDevice)
412 {
413 if (!createDevice())
414 {
415 return NULL;
416 }
417 }
apatrick@chromium.org9e83b592011-02-10 22:04:34 +0000418 else if (isDeviceLost()) // Lost device
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000419 {
420 if (!resetDevice())
421 {
422 return NULL;
423 }
424
425 // Restore any surfaces that may have been lost
426 for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
427 {
428 (*surface)->resetSwapChain();
429 }
430 }
431
432 const egl::Config *config = mConfigSet.get(configHandle);
433
434 gl::Context *context = glCreateContext(config, shareContext);
435 mContextSet.insert(context);
436
437 return context;
438}
439
440void Display::destroySurface(egl::Surface *surface)
441{
442 delete surface;
443 mSurfaceSet.erase(surface);
444}
445
446void Display::destroyContext(gl::Context *context)
447{
448 glDestroyContext(context);
449 mContextSet.erase(context);
450
apatrick@chromium.org9e83b592011-02-10 22:04:34 +0000451 if (mContextSet.empty() && mDevice && isDeviceLost()) // Last context of a lost device
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000452 {
453 for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
454 {
455 (*surface)->release();
456 }
457 }
458}
459
460bool Display::isInitialized()
461{
462 return mD3d9 != NULL && mConfigSet.size() > 0;
463}
464
465bool Display::isValidConfig(EGLConfig config)
466{
467 return mConfigSet.get(config) != NULL;
468}
469
470bool Display::isValidContext(gl::Context *context)
471{
472 return mContextSet.find(context) != mContextSet.end();
473}
474
475bool Display::isValidSurface(egl::Surface *surface)
476{
477 return mSurfaceSet.find(surface) != mSurfaceSet.end();
478}
479
480bool Display::hasExistingWindowSurface(HWND window)
481{
482 for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
483 {
484 if ((*surface)->getWindowHandle() == window)
485 {
486 return true;
487 }
488 }
489
490 return false;
491}
492
493EGLint Display::getMinSwapInterval()
494{
495 return mMinSwapInterval;
496}
497
498EGLint Display::getMaxSwapInterval()
499{
500 return mMaxSwapInterval;
501}
502
503IDirect3DDevice9 *Display::getDevice()
504{
505 if (!mDevice)
506 {
507 if (!createDevice())
508 {
509 return NULL;
510 }
511 }
512
513 return mDevice;
514}
515
516D3DCAPS9 Display::getDeviceCaps()
517{
518 return mDeviceCaps;
519}
520
apatrick@chromium.org9e83b592011-02-10 22:04:34 +0000521bool Display::isDeviceLost()
522{
523 if (mDeviceEx)
524 {
525 return FAILED(mDeviceEx->CheckDeviceState(NULL));
526 }
527 else
528 {
529 return FAILED(mDevice->TestCooperativeLevel());
530 }
531}
532
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000533void Display::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray)
534{
535 for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++)
536 {
537 HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format,
538 TRUE, (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL);
539
540 multiSampleArray[multiSampleIndex] = SUCCEEDED(result);
541 }
542}
543
544bool Display::getCompressedTextureSupport()
545{
546 D3DDISPLAYMODE currentDisplayMode;
547 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
548
549 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1));
550}
551
552bool Display::getFloatTextureSupport(bool *filtering, bool *renderable)
553{
554 D3DDISPLAYMODE currentDisplayMode;
555 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
556
557 *filtering = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
558 D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
559 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
560 D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
561
562 *renderable = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
563 D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F))&&
564 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
565 D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
566
567 if (!filtering && !renderable)
568 {
569 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
570 D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
571 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
572 D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
573 }
574 else
575 {
576 return true;
577 }
578}
579
580bool Display::getHalfFloatTextureSupport(bool *filtering, bool *renderable)
581{
582 D3DDISPLAYMODE currentDisplayMode;
583 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
584
585 *filtering = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
586 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
587 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
588 D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
589
590 *renderable = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
591 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
592 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
593 D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
594
595 if (!filtering && !renderable)
596 {
597 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
598 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
599 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
600 D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
601 }
602 else
603 {
604 return true;
605 }
606}
607
daniel@transgaming.comed828e52010-10-15 17:57:30 +0000608bool Display::getLuminanceTextureSupport()
609{
610 D3DDISPLAYMODE currentDisplayMode;
611 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
612
613 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_L8));
614}
615
616bool Display::getLuminanceAlphaTextureSupport()
617{
618 D3DDISPLAYMODE currentDisplayMode;
619 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
620
621 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8L8));
622}
623
daniel@transgaming.comee04e452011-01-08 05:46:27 +0000624D3DPOOL Display::getBufferPool(DWORD usage) const
daniel@transgaming.com37b141e2011-01-08 05:46:13 +0000625{
apatrick@chromium.org9e83b592011-02-10 22:04:34 +0000626 if (mD3d9Ex != NULL)
daniel@transgaming.comee04e452011-01-08 05:46:27 +0000627 {
628 return D3DPOOL_DEFAULT;
629 }
630 else
631 {
632 if (!(usage & D3DUSAGE_DYNAMIC))
633 {
634 return D3DPOOL_MANAGED;
635 }
636 }
637
638 return D3DPOOL_DEFAULT;
daniel@transgaming.com37b141e2011-01-08 05:46:13 +0000639}
640
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000641bool Display::getEventQuerySupport()
642{
643 IDirect3DQuery9 *query;
644 HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query);
645 if (SUCCEEDED(result))
646 {
647 query->Release();
648 }
649
650 return result != D3DERR_NOTAVAILABLE;
651}
652
653D3DPRESENT_PARAMETERS Display::getDefaultPresentParameters()
654{
655 D3DPRESENT_PARAMETERS presentParameters = {0};
656
657 // The default swap chain is never actually used. Surface will create a new swap chain with the proper parameters.
658 presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
659 presentParameters.BackBufferCount = 1;
660 presentParameters.BackBufferFormat = D3DFMT_UNKNOWN;
661 presentParameters.BackBufferWidth = 1;
662 presentParameters.BackBufferHeight = 1;
663 presentParameters.EnableAutoDepthStencil = FALSE;
664 presentParameters.Flags = 0;
665 presentParameters.hDeviceWindow = mDeviceWindow;
666 presentParameters.MultiSampleQuality = 0;
667 presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
668 presentParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
669 presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
670 presentParameters.Windowed = TRUE;
671
672 return presentParameters;
673}
daniel@transgaming.comd36c6a02010-08-31 12:15:09 +0000674}