blob: 283c0b812d53417f61a630e17eaf351a50236056 [file] [log] [blame]
daniel@transgaming.com621ce052012-10-31 17:52:29 +00001//
2// Copyright (c) 2012 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// Renderer.cpp: Implements a back-end specific class that hides the details of the
8// implementation-specific renderer.
9
daniel@transgaming.com621ce052012-10-31 17:52:29 +000010#include "common/debug.h"
11#include "libGLESv2/utilities.h"
daniel@transgaming.com2507f412012-10-31 18:46:48 +000012#include "libGLESv2/renderer/Renderer9.h"
daniel@transgaming.com621ce052012-10-31 17:52:29 +000013
daniel@transgaming.com3281f972012-10-31 18:38:51 +000014#include "libEGL/Config.h"
daniel@transgaming.comef21ab22012-10-31 17:52:47 +000015#include "libEGL/Display.h"
16
daniel@transgaming.com621ce052012-10-31 17:52:29 +000017// Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
18#define REF_RAST 0
19
20// The "Debug This Pixel..." feature in PIX often fails when using the
21// D3D9Ex interfaces. In order to get debug pixel to work on a Vista/Win 7
22// machine, define "ANGLE_ENABLE_D3D9EX=0" in your project file.
23#if !defined(ANGLE_ENABLE_D3D9EX)
24// Enables use of the IDirect3D9Ex interface, when available
25#define ANGLE_ENABLE_D3D9EX 1
26#endif // !defined(ANGLE_ENABLE_D3D9EX)
27
28namespace renderer
29{
daniel@transgaming.com2507f412012-10-31 18:46:48 +000030const D3DFORMAT Renderer9::mRenderTargetFormats[] =
daniel@transgaming.com92955622012-10-31 18:38:41 +000031 {
32 D3DFMT_A1R5G5B5,
33 // D3DFMT_A2R10G10B10, // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value.
34 D3DFMT_A8R8G8B8,
35 D3DFMT_R5G6B5,
36 // D3DFMT_X1R5G5B5, // Has no compatible OpenGL ES renderbuffer format
37 D3DFMT_X8R8G8B8
38 };
39
daniel@transgaming.com2507f412012-10-31 18:46:48 +000040const D3DFORMAT Renderer9::mDepthStencilFormats[] =
daniel@transgaming.com92955622012-10-31 18:38:41 +000041 {
42 D3DFMT_UNKNOWN,
43 // D3DFMT_D16_LOCKABLE,
44 D3DFMT_D32,
45 // D3DFMT_D15S1,
46 D3DFMT_D24S8,
47 D3DFMT_D24X8,
48 // D3DFMT_D24X4S4,
49 D3DFMT_D16,
50 // D3DFMT_D32F_LOCKABLE,
51 // D3DFMT_D24FS8
52 };
daniel@transgaming.com621ce052012-10-31 17:52:29 +000053
daniel@transgaming.com2507f412012-10-31 18:46:48 +000054Renderer9::Renderer9(egl::Display *display, HMODULE hModule, HDC hDc) : Renderer(display), mDc(hDc)
daniel@transgaming.com621ce052012-10-31 17:52:29 +000055{
56 mD3d9Module = hModule;
57
58 mD3d9 = NULL;
59 mD3d9Ex = NULL;
60 mDevice = NULL;
61 mDeviceEx = NULL;
62 mDeviceWindow = NULL;
63
64 mAdapter = D3DADAPTER_DEFAULT;
65
66 #if REF_RAST == 1 || defined(FORCE_REF_RAST)
67 mDeviceType = D3DDEVTYPE_REF;
68 #else
69 mDeviceType = D3DDEVTYPE_HAL;
70 #endif
71
72 mDeviceLost = false;
daniel@transgaming.comb7833982012-10-31 18:31:46 +000073
74 mMaxSupportedSamples = 0;
daniel@transgaming.com621ce052012-10-31 17:52:29 +000075}
76
daniel@transgaming.com2507f412012-10-31 18:46:48 +000077Renderer9::~Renderer9()
daniel@transgaming.com621ce052012-10-31 17:52:29 +000078{
daniel@transgaming.comef21ab22012-10-31 17:52:47 +000079 releaseDeviceResources();
80
daniel@transgaming.com621ce052012-10-31 17:52:29 +000081 if (mDevice)
82 {
83 // If the device is lost, reset it first to prevent leaving the driver in an unstable state
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +000084 if (testDeviceLost(false))
daniel@transgaming.com621ce052012-10-31 17:52:29 +000085 {
86 resetDevice();
87 }
88
89 mDevice->Release();
90 mDevice = NULL;
91 }
92
93 if (mDeviceEx)
94 {
95 mDeviceEx->Release();
96 mDeviceEx = NULL;
97 }
98
99 if (mD3d9)
100 {
101 mD3d9->Release();
102 mD3d9 = NULL;
103 }
104
105 if (mDeviceWindow)
106 {
107 DestroyWindow(mDeviceWindow);
108 mDeviceWindow = NULL;
109 }
110
111 if (mD3d9Ex)
112 {
113 mD3d9Ex->Release();
114 mD3d9Ex = NULL;
115 }
116
117 if (mD3d9Module)
118 {
119 mD3d9Module = NULL;
120 }
121
daniel@transgaming.comb7833982012-10-31 18:31:46 +0000122 while (!mMultiSampleSupport.empty())
123 {
124 delete [] mMultiSampleSupport.begin()->second;
125 mMultiSampleSupport.erase(mMultiSampleSupport.begin());
126 }
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000127}
128
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000129EGLint Renderer9::initialize()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000130{
131 typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**);
132 Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast<Direct3DCreate9ExFunc>(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex"));
133
134 // Use Direct3D9Ex if available. Among other things, this version is less
135 // inclined to report a lost context, for example when the user switches
136 // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available.
137 if (ANGLE_ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex)))
138 {
139 ASSERT(mD3d9Ex);
140 mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
141 ASSERT(mD3d9);
142 }
143 else
144 {
145 mD3d9 = Direct3DCreate9(D3D_SDK_VERSION);
146 }
147
148 if (!mD3d9)
149 {
150 ERR("Could not create D3D9 device - aborting!\n");
151 return EGL_NOT_INITIALIZED;
152 }
153 if (mDc != NULL)
154 {
155 // UNIMPLEMENTED(); // FIXME: Determine which adapter index the device context corresponds to
156 }
157
158 HRESULT result;
159
160 // Give up on getting device caps after about one second.
161 for (int i = 0; i < 10; ++i)
162 {
163 result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps);
164 if (SUCCEEDED(result))
165 {
166 break;
167 }
168 else if (result == D3DERR_NOTAVAILABLE)
169 {
170 Sleep(100); // Give the driver some time to initialize/recover
171 }
172 else if (FAILED(result)) // D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY, D3DERR_INVALIDDEVICE, or another error we can't recover from
173 {
174 ERR("failed to get device caps (0x%x)\n", result);
175 return EGL_NOT_INITIALIZED;
176 }
177 }
178
179 if (mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(2, 0))
180 {
181 ERR("Renderer does not support PS 2.0. aborting!\n");
182 return EGL_NOT_INITIALIZED;
183 }
184
185 // When DirectX9 is running with an older DirectX8 driver, a StretchRect from a regular texture to a render target texture is not supported.
186 // This is required by Texture2D::convertToRenderTarget.
187 if ((mDeviceCaps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) == 0)
188 {
189 ERR("Renderer does not support stretctrect from textures!\n");
190 return EGL_NOT_INITIALIZED;
191 }
192
193 mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier);
194
195 // ATI cards on XP have problems with non-power-of-two textures.
196 mSupportsNonPower2Textures = !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) &&
197 !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) &&
198 !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) &&
199 !(getComparableOSVersion() < versionWindowsVista && mAdapterIdentifier.VendorId == VENDOR_ID_AMD);
200
daniel@transgaming.comba0570e2012-10-31 18:07:39 +0000201 // Must support a minimum of 2:1 anisotropy for max anisotropy to be considered supported, per the spec
202 mSupportsTextureFilterAnisotropy = ((mDeviceCaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) && (mDeviceCaps.MaxAnisotropy >= 2));
203
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000204 mMinSwapInterval = 4;
205 mMaxSwapInterval = 0;
206
207 if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE)
208 {
209 mMinSwapInterval = std::min(mMinSwapInterval, 0);
210 mMaxSwapInterval = std::max(mMaxSwapInterval, 0);
211 }
212 if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE)
213 {
214 mMinSwapInterval = std::min(mMinSwapInterval, 1);
215 mMaxSwapInterval = std::max(mMaxSwapInterval, 1);
216 }
217 if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO)
218 {
219 mMinSwapInterval = std::min(mMinSwapInterval, 2);
220 mMaxSwapInterval = std::max(mMaxSwapInterval, 2);
221 }
222 if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE)
223 {
224 mMinSwapInterval = std::min(mMinSwapInterval, 3);
225 mMaxSwapInterval = std::max(mMaxSwapInterval, 3);
226 }
227 if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR)
228 {
229 mMinSwapInterval = std::min(mMinSwapInterval, 4);
230 mMaxSwapInterval = std::max(mMaxSwapInterval, 4);
231 }
232
daniel@transgaming.comb7833982012-10-31 18:31:46 +0000233 int max = 0;
daniel@transgaming.com92955622012-10-31 18:38:41 +0000234 for (int i = 0; i < sizeof(mRenderTargetFormats) / sizeof(D3DFORMAT); ++i)
daniel@transgaming.comb7833982012-10-31 18:31:46 +0000235 {
236 bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1];
daniel@transgaming.com92955622012-10-31 18:38:41 +0000237 getMultiSampleSupport(mRenderTargetFormats[i], multisampleArray);
238 mMultiSampleSupport[mRenderTargetFormats[i]] = multisampleArray;
239
240 for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j)
241 {
242 if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max)
243 {
244 max = j;
245 }
246 }
247 }
248
249 for (int i = 0; i < sizeof(mDepthStencilFormats) / sizeof(D3DFORMAT); ++i)
250 {
251 if (mDepthStencilFormats[i] == D3DFMT_UNKNOWN)
252 continue;
253
254 bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1];
255 getMultiSampleSupport(mDepthStencilFormats[i], multisampleArray);
256 mMultiSampleSupport[mDepthStencilFormats[i]] = multisampleArray;
daniel@transgaming.comb7833982012-10-31 18:31:46 +0000257
258 for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j)
259 {
260 if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max)
261 {
262 max = j;
263 }
264 }
265 }
266
267 mMaxSupportedSamples = max;
268
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000269 static const TCHAR windowName[] = TEXT("AngleHiddenWindow");
270 static const TCHAR className[] = TEXT("STATIC");
271
272 mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
273
274 D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
275 DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;
276
277 result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice);
278 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST)
279 {
280 return EGL_BAD_ALLOC;
281 }
282
283 if (FAILED(result))
284 {
285 result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice);
286
287 if (FAILED(result))
288 {
289 ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_NOTAVAILABLE || result == D3DERR_DEVICELOST);
290 return EGL_BAD_ALLOC;
291 }
292 }
293
294 if (mD3d9Ex)
295 {
296 result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**) &mDeviceEx);
297 ASSERT(SUCCEEDED(result));
298 }
299
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000300 mVertexShaderCache.initialize(mDevice);
301 mPixelShaderCache.initialize(mDevice);
302
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000303 initializeDevice();
304
305 return EGL_SUCCESS;
306}
307
308// do any one-time device initialization
309// NOTE: this is also needed after a device lost/reset
310// to reset the scene status and ensure the default states are reset.
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000311void Renderer9::initializeDevice()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000312{
313 // Permanent non-default states
314 mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
315 mDevice->SetRenderState(D3DRS_LASTPIXEL, FALSE);
316
317 if (mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0))
318 {
319 mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, (DWORD&)mDeviceCaps.MaxPointSize);
320 }
321 else
322 {
323 mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, 0x3F800000); // 1.0f
324 }
325
326 mSceneStarted = false;
327}
328
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000329D3DPRESENT_PARAMETERS Renderer9::getDefaultPresentParameters()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000330{
331 D3DPRESENT_PARAMETERS presentParameters = {0};
332
333 // The default swap chain is never actually used. Surface will create a new swap chain with the proper parameters.
334 presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
335 presentParameters.BackBufferCount = 1;
336 presentParameters.BackBufferFormat = D3DFMT_UNKNOWN;
337 presentParameters.BackBufferWidth = 1;
338 presentParameters.BackBufferHeight = 1;
339 presentParameters.EnableAutoDepthStencil = FALSE;
340 presentParameters.Flags = 0;
341 presentParameters.hDeviceWindow = mDeviceWindow;
342 presentParameters.MultiSampleQuality = 0;
343 presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
344 presentParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
345 presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
346 presentParameters.Windowed = TRUE;
347
348 return presentParameters;
349}
350
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000351int Renderer9::generateConfigs(ConfigDesc **configDescList)
daniel@transgaming.com3281f972012-10-31 18:38:51 +0000352{
353 D3DDISPLAYMODE currentDisplayMode;
354 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
355
356 int numRenderFormats = sizeof(mRenderTargetFormats) / sizeof(mRenderTargetFormats[0]);
357 int numDepthFormats = sizeof(mDepthStencilFormats) / sizeof(mDepthStencilFormats[0]);
358 (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
359 int numConfigs = 0;
360
361 for (int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
362 {
363 D3DFORMAT renderTargetFormat = mRenderTargetFormats[formatIndex];
364
365 HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat);
366
367 if (SUCCEEDED(result))
368 {
369 for (int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
370 {
371 D3DFORMAT depthStencilFormat = mDepthStencilFormats[depthStencilIndex];
372 HRESULT result = D3D_OK;
373
374 if(depthStencilFormat != D3DFMT_UNKNOWN)
375 {
376 result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat);
377 }
378
379 if (SUCCEEDED(result))
380 {
381 if(depthStencilFormat != D3DFMT_UNKNOWN)
382 {
383 result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat);
384 }
385
386 if (SUCCEEDED(result))
387 {
388 ConfigDesc newConfig;
389 newConfig.renderTargetFormat = dx2es::ConvertBackBufferFormat(renderTargetFormat);
390 newConfig.depthStencilFormat = dx2es::ConvertDepthStencilFormat(depthStencilFormat);
391 newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
392 newConfig.fastConfig = (currentDisplayMode.Format == renderTargetFormat);
393
394 (*configDescList)[numConfigs++] = newConfig;
395 }
396 }
397 }
398 }
399 }
400
401 return numConfigs;
402}
403
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000404void Renderer9::deleteConfigs(ConfigDesc *configDescList)
daniel@transgaming.com3281f972012-10-31 18:38:51 +0000405{
406 delete [] (configDescList);
407}
408
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000409void Renderer9::startScene()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000410{
411 if (!mSceneStarted)
412 {
413 long result = mDevice->BeginScene();
414 if (SUCCEEDED(result)) {
415 // This is defensive checking against the device being
416 // lost at unexpected times.
417 mSceneStarted = true;
418 }
419 }
420}
421
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000422void Renderer9::endScene()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000423{
424 if (mSceneStarted)
425 {
426 // EndScene can fail if the device was lost, for example due
427 // to a TDR during a draw call.
428 mDevice->EndScene();
429 mSceneStarted = false;
430 }
431}
432
daniel@transgaming.comef21ab22012-10-31 17:52:47 +0000433// D3D9_REPLACE
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000434void Renderer9::sync(bool block)
daniel@transgaming.comef21ab22012-10-31 17:52:47 +0000435{
436 HRESULT result;
437
438 IDirect3DQuery9* query = allocateEventQuery();
439 if (!query)
440 {
441 return;
442 }
443
444 result = query->Issue(D3DISSUE_END);
445 ASSERT(SUCCEEDED(result));
446
447 do
448 {
449 result = query->GetData(NULL, 0, D3DGETDATA_FLUSH);
450
451 if(block && result == S_FALSE)
452 {
453 // Keep polling, but allow other threads to do something useful first
454 Sleep(0);
455 // explicitly check for device loss
456 // some drivers seem to return S_FALSE even if the device is lost
457 // instead of D3DERR_DEVICELOST like they should
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000458 if (testDeviceLost(false))
daniel@transgaming.comef21ab22012-10-31 17:52:47 +0000459 {
460 result = D3DERR_DEVICELOST;
461 }
462 }
463 }
464 while(block && result == S_FALSE);
465
466 freeEventQuery(query);
467
468 if (isDeviceLostError(result))
469 {
470 mDisplay->notifyDeviceLost();
471 }
472}
473
474// D3D9_REPLACE
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000475IDirect3DQuery9* Renderer9::allocateEventQuery()
daniel@transgaming.comef21ab22012-10-31 17:52:47 +0000476{
477 IDirect3DQuery9 *query = NULL;
478
479 if (mEventQueryPool.empty())
480 {
481 HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query);
482 ASSERT(SUCCEEDED(result));
483 }
484 else
485 {
486 query = mEventQueryPool.back();
487 mEventQueryPool.pop_back();
488 }
489
490 return query;
491}
492
493// D3D9_REPLACE
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000494void Renderer9::freeEventQuery(IDirect3DQuery9* query)
daniel@transgaming.comef21ab22012-10-31 17:52:47 +0000495{
496 if (mEventQueryPool.size() > 1000)
497 {
498 query->Release();
499 }
500 else
501 {
502 mEventQueryPool.push_back(query);
503 }
504}
505
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000506IDirect3DVertexShader9 *Renderer9::createVertexShader(const DWORD *function, size_t length)
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000507{
508 return mVertexShaderCache.create(function, length);
509}
510
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000511IDirect3DPixelShader9 *Renderer9::createPixelShader(const DWORD *function, size_t length)
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000512{
513 return mPixelShaderCache.create(function, length);
514}
515
daniel@transgaming.com113f0eb2012-10-31 18:46:58 +0000516HRESULT Renderer9::createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer)
517{
518 D3DPOOL Pool = getBufferPool(Usage);
519 return mDevice->CreateVertexBuffer(Length, Usage, 0, Pool, ppVertexBuffer, NULL);
520}
521
522HRESULT Renderer9::createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer)
523{
524 D3DPOOL Pool = getBufferPool(Usage);
525 return mDevice->CreateIndexBuffer(Length, Usage, Format, Pool, ppIndexBuffer, NULL);
526}
daniel@transgaming.comba0570e2012-10-31 18:07:39 +0000527
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000528void Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
daniel@transgaming.comba0570e2012-10-31 18:07:39 +0000529{
530 int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0;
531 int d3dSampler = index + d3dSamplerOffset;
532
533 mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, es2dx::ConvertTextureWrap(samplerState.wrapS));
534 mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, es2dx::ConvertTextureWrap(samplerState.wrapT));
535
536 mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, es2dx::ConvertMagFilter(samplerState.magFilter, samplerState.maxAnisotropy));
537 D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter;
538 es2dx::ConvertMinFilter(samplerState.minFilter, &d3dMinFilter, &d3dMipFilter, samplerState.maxAnisotropy);
539 mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter);
540 mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter);
541 mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, samplerState.lodOffset);
542 if (mSupportsTextureFilterAnisotropy)
543 {
544 mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy);
545 }
546}
547
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000548void Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
daniel@transgaming.coma734f272012-10-31 18:07:48 +0000549{
550 int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0;
551 int d3dSampler = index + d3dSamplerOffset;
552 IDirect3DBaseTexture9 *d3dTexture = NULL;
553
554 if (texture)
555 {
556 d3dTexture = texture->getD3DTexture();
557 // If we get NULL back from getTexture here, something went wrong
558 // in the texture class and we're unexpectedly missing the d3d texture
559 ASSERT(d3dTexture != NULL);
560 }
561
562 mDevice->SetTexture(d3dSampler, d3dTexture);
563}
564
565
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000566void Renderer9::releaseDeviceResources()
daniel@transgaming.comef21ab22012-10-31 17:52:47 +0000567{
568 while (!mEventQueryPool.empty())
569 {
570 mEventQueryPool.back()->Release();
571 mEventQueryPool.pop_back();
572 }
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000573
574 mVertexShaderCache.clear();
575 mPixelShaderCache.clear();
daniel@transgaming.comef21ab22012-10-31 17:52:47 +0000576}
577
578
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000579void Renderer9::markDeviceLost()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000580{
581 mDeviceLost = true;
582}
583
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000584bool Renderer9::isDeviceLost()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000585{
586 return mDeviceLost;
587}
588
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000589// set notify to true to broadcast a message to all contexts of the device loss
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000590bool Renderer9::testDeviceLost(bool notify)
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000591{
592 bool isLost = false;
593
594 if (mDeviceEx)
595 {
596 isLost = FAILED(mDeviceEx->CheckDeviceState(NULL));
597 }
598 else if (mDevice)
599 {
600 isLost = FAILED(mDevice->TestCooperativeLevel());
601 }
602 else
603 {
604 // No device yet, so no reset required
605 }
606
607 if (isLost)
608 {
609 // ensure we note the device loss --
610 // we'll probably get this done again by markDeviceLost
611 // but best to remember it!
612 // Note that we don't want to clear the device loss status here
613 // -- this needs to be done by resetDevice
614 mDeviceLost = true;
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000615 if (notify)
616 {
617 mDisplay->notifyDeviceLost();
618 }
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000619 }
620
621 return isLost;
622}
623
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000624bool Renderer9::testDeviceResettable()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000625{
626 HRESULT status = D3D_OK;
627
628 if (mDeviceEx)
629 {
630 status = mDeviceEx->CheckDeviceState(NULL);
631 }
632 else if (mDevice)
633 {
634 status = mDevice->TestCooperativeLevel();
635 }
636
637 switch (status)
638 {
639 case D3DERR_DEVICENOTRESET:
640 case D3DERR_DEVICEHUNG:
641 return true;
642 default:
643 return false;
644 }
645}
646
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000647bool Renderer9::resetDevice()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000648{
daniel@transgaming.comef21ab22012-10-31 17:52:47 +0000649 releaseDeviceResources();
650
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000651 D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
652
653 HRESULT result = D3D_OK;
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000654 bool lost = testDeviceLost(false);
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000655 int attempts = 3;
656
657 while (lost && attempts > 0)
658 {
659 if (mDeviceEx)
660 {
661 Sleep(500); // Give the graphics driver some CPU time
662 result = mDeviceEx->ResetEx(&presentParameters, NULL);
663 }
664 else
665 {
666 result = mDevice->TestCooperativeLevel();
667 while (result == D3DERR_DEVICELOST)
668 {
669 Sleep(100); // Give the graphics driver some CPU time
670 result = mDevice->TestCooperativeLevel();
671 }
672
673 if (result == D3DERR_DEVICENOTRESET)
674 {
675 result = mDevice->Reset(&presentParameters);
676 }
677 }
678
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000679 lost = testDeviceLost(false);
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000680 attempts --;
681 }
682
683 if (FAILED(result))
684 {
685 ERR("Reset/ResetEx failed multiple times: 0x%08X", result);
686 return false;
687 }
688
689 // reset device defaults
690 initializeDevice();
691 mDeviceLost = false;
692
693 return true;
694}
695
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000696DWORD Renderer9::getAdapterVendor() const
daniel@transgaming.com4ca789e2012-10-31 18:46:40 +0000697{
698 return mAdapterIdentifier.VendorId;
699}
700
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000701const char *Renderer9::getAdapterDescription() const
daniel@transgaming.com4ca789e2012-10-31 18:46:40 +0000702{
703 return mAdapterIdentifier.Description;
704}
705
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000706GUID Renderer9::getAdapterIdentifier() const
daniel@transgaming.com4ca789e2012-10-31 18:46:40 +0000707{
708 return mAdapterIdentifier.DeviceIdentifier;
709}
710
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000711void Renderer9::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray)
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000712{
713 for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++)
714 {
715 HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format,
716 TRUE, (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL);
717
718 multiSampleArray[multiSampleIndex] = SUCCEEDED(result);
719 }
720}
721
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000722bool Renderer9::getDXT1TextureSupport()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000723{
724 D3DDISPLAYMODE currentDisplayMode;
725 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
726
727 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1));
728}
729
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000730bool Renderer9::getDXT3TextureSupport()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000731{
732 D3DDISPLAYMODE currentDisplayMode;
733 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
734
735 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT3));
736}
737
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000738bool Renderer9::getDXT5TextureSupport()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000739{
740 D3DDISPLAYMODE currentDisplayMode;
741 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
742
743 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT5));
744}
745
746// we use INTZ for depth textures in Direct3D9
747// we also want NULL texture support to ensure the we can make depth-only FBOs
748// see http://aras-p.info/texts/D3D9GPUHacks.html
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000749bool Renderer9::getDepthTextureSupport() const
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000750{
751 D3DDISPLAYMODE currentDisplayMode;
752 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
753
754 bool intz = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format,
755 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, D3DFMT_INTZ));
756 bool null = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format,
757 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL));
758
759 return intz && null;
760}
761
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000762bool Renderer9::getFloat32TextureSupport(bool *filtering, bool *renderable)
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000763{
764 D3DDISPLAYMODE currentDisplayMode;
765 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
766
767 *filtering = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
768 D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
769 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
770 D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
771
772 *renderable = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
773 D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F))&&
774 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
775 D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
776
777 if (!*filtering && !*renderable)
778 {
779 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
780 D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
781 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
782 D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
783 }
784 else
785 {
786 return true;
787 }
788}
789
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000790bool Renderer9::getFloat16TextureSupport(bool *filtering, bool *renderable)
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000791{
792 D3DDISPLAYMODE currentDisplayMode;
793 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
794
795 *filtering = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
796 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
797 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
798 D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
799
800 *renderable = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
801 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
802 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
803 D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
804
805 if (!*filtering && !*renderable)
806 {
807 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
808 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
809 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
810 D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
811 }
812 else
813 {
814 return true;
815 }
816}
817
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000818bool Renderer9::getLuminanceTextureSupport()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000819{
820 D3DDISPLAYMODE currentDisplayMode;
821 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
822
823 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_L8));
824}
825
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000826bool Renderer9::getLuminanceAlphaTextureSupport()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000827{
828 D3DDISPLAYMODE currentDisplayMode;
829 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
830
831 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8L8));
832}
833
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000834bool Renderer9::getTextureFilterAnisotropySupport() const
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000835{
daniel@transgaming.comba0570e2012-10-31 18:07:39 +0000836 return mSupportsTextureFilterAnisotropy;
837}
838
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000839float Renderer9::getTextureMaxAnisotropy() const
daniel@transgaming.comba0570e2012-10-31 18:07:39 +0000840{
841 if (mSupportsTextureFilterAnisotropy)
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000842 {
843 return mDeviceCaps.MaxAnisotropy;
844 }
845 return 1.0f;
846}
847
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000848bool Renderer9::getEventQuerySupport()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000849{
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000850 IDirect3DQuery9 *query = allocateEventQuery();
851 if (query)
852 {
853 freeEventQuery(query);
854 return true;
855 }
856 else
857 {
858 return false;
859 }
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000860 return true;
861}
862
863// Only Direct3D 10 ready devices support all the necessary vertex texture formats.
864// We test this using D3D9 by checking support for the R16F format.
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000865bool Renderer9::getVertexTextureSupport() const
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000866{
867 if (!mDevice || mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(3, 0))
868 {
869 return false;
870 }
871
872 D3DDISPLAYMODE currentDisplayMode;
873 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
874
875 HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F);
876
877 return SUCCEEDED(result);
878}
879
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000880bool Renderer9::getNonPower2TextureSupport() const
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000881{
882 return mSupportsNonPower2Textures;
883}
884
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000885bool Renderer9::getOcclusionQuerySupport() const
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000886{
887 if (!mDevice)
888 {
889 return false;
890 }
891
892 IDirect3DQuery9 *query = NULL;
893 HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, &query);
894 if (SUCCEEDED(result) && query)
895 {
896 query->Release();
897 return true;
898 }
899 else
900 {
901 return false;
902 }
903}
904
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000905bool Renderer9::getInstancingSupport() const
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000906{
907 return mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0);
908}
909
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000910bool Renderer9::getShareHandleSupport() const
daniel@transgaming.com313e3922012-10-31 17:52:39 +0000911{
912 // PIX doesn't seem to support using share handles, so disable them.
913 // D3D9_REPLACE
daniel@transgaming.com7cb796e2012-10-31 18:46:44 +0000914 return (mD3d9Ex != NULL) && !gl::perfActive();
daniel@transgaming.com313e3922012-10-31 17:52:39 +0000915}
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000916
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000917bool Renderer9::getShaderModel3Support() const
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000918{
919 return mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0);
920}
921
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000922float Renderer9::getMaxPointSize() const
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000923{
924 return mDeviceCaps.MaxPointSize;
925}
926
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000927int Renderer9::getMaxTextureWidth() const
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000928{
929 return (int)mDeviceCaps.MaxTextureWidth;
930}
931
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000932int Renderer9::getMaxTextureHeight() const
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000933{
934 return (int)mDeviceCaps.MaxTextureHeight;
935}
936
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000937bool Renderer9::get32BitIndexSupport() const
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000938{
939 return mDeviceCaps.MaxVertexIndex >= (1 << 16);
940}
941
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000942DWORD Renderer9::getCapsDeclTypes() const
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000943{
944 return mDeviceCaps.DeclTypes;
945}
946
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000947int Renderer9::getMinSwapInterval() const
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000948{
949 return mMinSwapInterval;
950}
951
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000952int Renderer9::getMaxSwapInterval() const
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000953{
954 return mMaxSwapInterval;
955}
956
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000957int Renderer9::getMaxSupportedSamples() const
daniel@transgaming.comb7833982012-10-31 18:31:46 +0000958{
959 return mMaxSupportedSamples;
960}
961
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000962int Renderer9::getNearestSupportedSamples(D3DFORMAT format, int requested) const
daniel@transgaming.comb7833982012-10-31 18:31:46 +0000963{
964 if (requested == 0)
965 {
966 return requested;
967 }
968
969 std::map<D3DFORMAT, bool *>::const_iterator itr = mMultiSampleSupport.find(format);
970 if (itr == mMultiSampleSupport.end())
971 {
daniel@transgaming.com92955622012-10-31 18:38:41 +0000972 if (format == D3DFMT_UNKNOWN)
973 return 0;
daniel@transgaming.comb7833982012-10-31 18:31:46 +0000974 return -1;
975 }
976
977 for (int i = requested; i <= D3DMULTISAMPLE_16_SAMPLES; ++i)
978 {
979 if (itr->second[i] && i != D3DMULTISAMPLE_NONMASKABLE)
980 {
981 return i;
982 }
983 }
984
985 return -1;
986}
987
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000988D3DPOOL Renderer9::getBufferPool(DWORD usage) const
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000989{
990 if (mD3d9Ex != NULL)
991 {
992 return D3DPOOL_DEFAULT;
993 }
994 else
995 {
996 if (!(usage & D3DUSAGE_DYNAMIC))
997 {
998 return D3DPOOL_MANAGED;
999 }
1000 }
1001
1002 return D3DPOOL_DEFAULT;
1003}
1004
daniel@transgaming.com2507f412012-10-31 18:46:48 +00001005D3DPOOL Renderer9::getTexturePool(DWORD usage) const
daniel@transgaming.com621ce052012-10-31 17:52:29 +00001006{
1007 if (mD3d9Ex != NULL)
1008 {
1009 return D3DPOOL_DEFAULT;
1010 }
1011 else
1012 {
1013 if (!(usage & (D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_RENDERTARGET)))
1014 {
1015 return D3DPOOL_MANAGED;
1016 }
1017 }
1018
1019 return D3DPOOL_DEFAULT;
1020}
1021
1022}