blob: 275938f8f08b6e2b20bfc561ecf92789353ceddf [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.comba0570e2012-10-31 18:07:39 +0000516
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000517void Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
daniel@transgaming.comba0570e2012-10-31 18:07:39 +0000518{
519 int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0;
520 int d3dSampler = index + d3dSamplerOffset;
521
522 mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, es2dx::ConvertTextureWrap(samplerState.wrapS));
523 mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, es2dx::ConvertTextureWrap(samplerState.wrapT));
524
525 mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, es2dx::ConvertMagFilter(samplerState.magFilter, samplerState.maxAnisotropy));
526 D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter;
527 es2dx::ConvertMinFilter(samplerState.minFilter, &d3dMinFilter, &d3dMipFilter, samplerState.maxAnisotropy);
528 mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter);
529 mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter);
530 mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, samplerState.lodOffset);
531 if (mSupportsTextureFilterAnisotropy)
532 {
533 mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy);
534 }
535}
536
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000537void Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
daniel@transgaming.coma734f272012-10-31 18:07:48 +0000538{
539 int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0;
540 int d3dSampler = index + d3dSamplerOffset;
541 IDirect3DBaseTexture9 *d3dTexture = NULL;
542
543 if (texture)
544 {
545 d3dTexture = texture->getD3DTexture();
546 // If we get NULL back from getTexture here, something went wrong
547 // in the texture class and we're unexpectedly missing the d3d texture
548 ASSERT(d3dTexture != NULL);
549 }
550
551 mDevice->SetTexture(d3dSampler, d3dTexture);
552}
553
554
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000555void Renderer9::releaseDeviceResources()
daniel@transgaming.comef21ab22012-10-31 17:52:47 +0000556{
557 while (!mEventQueryPool.empty())
558 {
559 mEventQueryPool.back()->Release();
560 mEventQueryPool.pop_back();
561 }
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000562
563 mVertexShaderCache.clear();
564 mPixelShaderCache.clear();
daniel@transgaming.comef21ab22012-10-31 17:52:47 +0000565}
566
567
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000568void Renderer9::markDeviceLost()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000569{
570 mDeviceLost = true;
571}
572
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000573bool Renderer9::isDeviceLost()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000574{
575 return mDeviceLost;
576}
577
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000578// set notify to true to broadcast a message to all contexts of the device loss
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000579bool Renderer9::testDeviceLost(bool notify)
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000580{
581 bool isLost = false;
582
583 if (mDeviceEx)
584 {
585 isLost = FAILED(mDeviceEx->CheckDeviceState(NULL));
586 }
587 else if (mDevice)
588 {
589 isLost = FAILED(mDevice->TestCooperativeLevel());
590 }
591 else
592 {
593 // No device yet, so no reset required
594 }
595
596 if (isLost)
597 {
598 // ensure we note the device loss --
599 // we'll probably get this done again by markDeviceLost
600 // but best to remember it!
601 // Note that we don't want to clear the device loss status here
602 // -- this needs to be done by resetDevice
603 mDeviceLost = true;
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000604 if (notify)
605 {
606 mDisplay->notifyDeviceLost();
607 }
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000608 }
609
610 return isLost;
611}
612
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000613bool Renderer9::testDeviceResettable()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000614{
615 HRESULT status = D3D_OK;
616
617 if (mDeviceEx)
618 {
619 status = mDeviceEx->CheckDeviceState(NULL);
620 }
621 else if (mDevice)
622 {
623 status = mDevice->TestCooperativeLevel();
624 }
625
626 switch (status)
627 {
628 case D3DERR_DEVICENOTRESET:
629 case D3DERR_DEVICEHUNG:
630 return true;
631 default:
632 return false;
633 }
634}
635
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000636bool Renderer9::resetDevice()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000637{
daniel@transgaming.comef21ab22012-10-31 17:52:47 +0000638 releaseDeviceResources();
639
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000640 D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
641
642 HRESULT result = D3D_OK;
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000643 bool lost = testDeviceLost(false);
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000644 int attempts = 3;
645
646 while (lost && attempts > 0)
647 {
648 if (mDeviceEx)
649 {
650 Sleep(500); // Give the graphics driver some CPU time
651 result = mDeviceEx->ResetEx(&presentParameters, NULL);
652 }
653 else
654 {
655 result = mDevice->TestCooperativeLevel();
656 while (result == D3DERR_DEVICELOST)
657 {
658 Sleep(100); // Give the graphics driver some CPU time
659 result = mDevice->TestCooperativeLevel();
660 }
661
662 if (result == D3DERR_DEVICENOTRESET)
663 {
664 result = mDevice->Reset(&presentParameters);
665 }
666 }
667
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000668 lost = testDeviceLost(false);
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000669 attempts --;
670 }
671
672 if (FAILED(result))
673 {
674 ERR("Reset/ResetEx failed multiple times: 0x%08X", result);
675 return false;
676 }
677
678 // reset device defaults
679 initializeDevice();
680 mDeviceLost = false;
681
682 return true;
683}
684
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000685DWORD Renderer9::getAdapterVendor() const
daniel@transgaming.com4ca789e2012-10-31 18:46:40 +0000686{
687 return mAdapterIdentifier.VendorId;
688}
689
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000690const char *Renderer9::getAdapterDescription() const
daniel@transgaming.com4ca789e2012-10-31 18:46:40 +0000691{
692 return mAdapterIdentifier.Description;
693}
694
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000695GUID Renderer9::getAdapterIdentifier() const
daniel@transgaming.com4ca789e2012-10-31 18:46:40 +0000696{
697 return mAdapterIdentifier.DeviceIdentifier;
698}
699
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000700void Renderer9::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray)
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000701{
702 for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++)
703 {
704 HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format,
705 TRUE, (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL);
706
707 multiSampleArray[multiSampleIndex] = SUCCEEDED(result);
708 }
709}
710
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000711bool Renderer9::getDXT1TextureSupport()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000712{
713 D3DDISPLAYMODE currentDisplayMode;
714 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
715
716 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1));
717}
718
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000719bool Renderer9::getDXT3TextureSupport()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000720{
721 D3DDISPLAYMODE currentDisplayMode;
722 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
723
724 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT3));
725}
726
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000727bool Renderer9::getDXT5TextureSupport()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000728{
729 D3DDISPLAYMODE currentDisplayMode;
730 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
731
732 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT5));
733}
734
735// we use INTZ for depth textures in Direct3D9
736// we also want NULL texture support to ensure the we can make depth-only FBOs
737// see http://aras-p.info/texts/D3D9GPUHacks.html
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000738bool Renderer9::getDepthTextureSupport() const
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000739{
740 D3DDISPLAYMODE currentDisplayMode;
741 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
742
743 bool intz = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format,
744 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, D3DFMT_INTZ));
745 bool null = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format,
746 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL));
747
748 return intz && null;
749}
750
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000751bool Renderer9::getFloat32TextureSupport(bool *filtering, bool *renderable)
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000752{
753 D3DDISPLAYMODE currentDisplayMode;
754 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
755
756 *filtering = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
757 D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
758 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
759 D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
760
761 *renderable = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
762 D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F))&&
763 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
764 D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
765
766 if (!*filtering && !*renderable)
767 {
768 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
769 D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
770 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
771 D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
772 }
773 else
774 {
775 return true;
776 }
777}
778
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000779bool Renderer9::getFloat16TextureSupport(bool *filtering, bool *renderable)
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000780{
781 D3DDISPLAYMODE currentDisplayMode;
782 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
783
784 *filtering = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
785 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
786 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
787 D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
788
789 *renderable = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
790 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
791 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
792 D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
793
794 if (!*filtering && !*renderable)
795 {
796 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
797 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
798 SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
799 D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
800 }
801 else
802 {
803 return true;
804 }
805}
806
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000807bool Renderer9::getLuminanceTextureSupport()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000808{
809 D3DDISPLAYMODE currentDisplayMode;
810 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
811
812 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_L8));
813}
814
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000815bool Renderer9::getLuminanceAlphaTextureSupport()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000816{
817 D3DDISPLAYMODE currentDisplayMode;
818 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
819
820 return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8L8));
821}
822
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000823bool Renderer9::getTextureFilterAnisotropySupport() const
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000824{
daniel@transgaming.comba0570e2012-10-31 18:07:39 +0000825 return mSupportsTextureFilterAnisotropy;
826}
827
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000828float Renderer9::getTextureMaxAnisotropy() const
daniel@transgaming.comba0570e2012-10-31 18:07:39 +0000829{
830 if (mSupportsTextureFilterAnisotropy)
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000831 {
832 return mDeviceCaps.MaxAnisotropy;
833 }
834 return 1.0f;
835}
836
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000837bool Renderer9::getEventQuerySupport()
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000838{
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000839 IDirect3DQuery9 *query = allocateEventQuery();
840 if (query)
841 {
842 freeEventQuery(query);
843 return true;
844 }
845 else
846 {
847 return false;
848 }
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000849 return true;
850}
851
852// Only Direct3D 10 ready devices support all the necessary vertex texture formats.
853// We test this using D3D9 by checking support for the R16F format.
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000854bool Renderer9::getVertexTextureSupport() const
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000855{
856 if (!mDevice || mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(3, 0))
857 {
858 return false;
859 }
860
861 D3DDISPLAYMODE currentDisplayMode;
862 mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
863
864 HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F);
865
866 return SUCCEEDED(result);
867}
868
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000869bool Renderer9::getNonPower2TextureSupport() const
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000870{
871 return mSupportsNonPower2Textures;
872}
873
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000874bool Renderer9::getOcclusionQuerySupport() const
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000875{
876 if (!mDevice)
877 {
878 return false;
879 }
880
881 IDirect3DQuery9 *query = NULL;
882 HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, &query);
883 if (SUCCEEDED(result) && query)
884 {
885 query->Release();
886 return true;
887 }
888 else
889 {
890 return false;
891 }
892}
893
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000894bool Renderer9::getInstancingSupport() const
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000895{
896 return mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0);
897}
898
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000899bool Renderer9::getShareHandleSupport() const
daniel@transgaming.com313e3922012-10-31 17:52:39 +0000900{
901 // PIX doesn't seem to support using share handles, so disable them.
902 // D3D9_REPLACE
daniel@transgaming.com7cb796e2012-10-31 18:46:44 +0000903 return (mD3d9Ex != NULL) && !gl::perfActive();
daniel@transgaming.com313e3922012-10-31 17:52:39 +0000904}
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000905
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000906bool Renderer9::getShaderModel3Support() const
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000907{
908 return mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0);
909}
910
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000911float Renderer9::getMaxPointSize() const
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000912{
913 return mDeviceCaps.MaxPointSize;
914}
915
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000916int Renderer9::getMaxTextureWidth() const
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000917{
918 return (int)mDeviceCaps.MaxTextureWidth;
919}
920
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000921int Renderer9::getMaxTextureHeight() const
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000922{
923 return (int)mDeviceCaps.MaxTextureHeight;
924}
925
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000926bool Renderer9::get32BitIndexSupport() const
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000927{
928 return mDeviceCaps.MaxVertexIndex >= (1 << 16);
929}
930
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000931DWORD Renderer9::getCapsDeclTypes() const
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000932{
933 return mDeviceCaps.DeclTypes;
934}
935
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000936int Renderer9::getMinSwapInterval() const
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000937{
938 return mMinSwapInterval;
939}
940
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000941int Renderer9::getMaxSwapInterval() const
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000942{
943 return mMaxSwapInterval;
944}
945
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000946int Renderer9::getMaxSupportedSamples() const
daniel@transgaming.comb7833982012-10-31 18:31:46 +0000947{
948 return mMaxSupportedSamples;
949}
950
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000951int Renderer9::getNearestSupportedSamples(D3DFORMAT format, int requested) const
daniel@transgaming.comb7833982012-10-31 18:31:46 +0000952{
953 if (requested == 0)
954 {
955 return requested;
956 }
957
958 std::map<D3DFORMAT, bool *>::const_iterator itr = mMultiSampleSupport.find(format);
959 if (itr == mMultiSampleSupport.end())
960 {
daniel@transgaming.com92955622012-10-31 18:38:41 +0000961 if (format == D3DFMT_UNKNOWN)
962 return 0;
daniel@transgaming.comb7833982012-10-31 18:31:46 +0000963 return -1;
964 }
965
966 for (int i = requested; i <= D3DMULTISAMPLE_16_SAMPLES; ++i)
967 {
968 if (itr->second[i] && i != D3DMULTISAMPLE_NONMASKABLE)
969 {
970 return i;
971 }
972 }
973
974 return -1;
975}
976
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000977D3DPOOL Renderer9::getBufferPool(DWORD usage) const
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000978{
979 if (mD3d9Ex != NULL)
980 {
981 return D3DPOOL_DEFAULT;
982 }
983 else
984 {
985 if (!(usage & D3DUSAGE_DYNAMIC))
986 {
987 return D3DPOOL_MANAGED;
988 }
989 }
990
991 return D3DPOOL_DEFAULT;
992}
993
daniel@transgaming.com2507f412012-10-31 18:46:48 +0000994D3DPOOL Renderer9::getTexturePool(DWORD usage) const
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000995{
996 if (mD3d9Ex != NULL)
997 {
998 return D3DPOOL_DEFAULT;
999 }
1000 else
1001 {
1002 if (!(usage & (D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_RENDERTARGET)))
1003 {
1004 return D3DPOOL_MANAGED;
1005 }
1006 }
1007
1008 return D3DPOOL_DEFAULT;
1009}
1010
1011}