4
4
(Object-oriented Graphics Rendering Engine)
5
5
For the latest info, see http://www.ogre3d.org/
7
Copyright (c) 2000-2006 Torus Knot Software Ltd
8
Also see acknowledgements in Readme.html
10
This program is free software; you can redistribute it and/or modify it under
11
the terms of the GNU Lesser General Public License as published by the Free Software
12
Foundation; either version 2 of the License, or (at your option) any later
15
This program is distributed in the hope that it will be useful, but WITHOUT
16
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
19
You should have received a copy of the GNU Lesser General Public License along with
20
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22
http://www.gnu.org/copyleft/lesser.txt.
24
You may alternatively use this source under the terms of a specific version of
25
the OGRE Unrestricted License provided you have obtained such a license from
26
Torus Knot Software Ltd.
7
Copyright (c) 2000-2009 Torus Knot Software Ltd
9
Permission is hereby granted, free of charge, to any person obtaining a copy
10
of this software and associated documentation files (the "Software"), to deal
11
in the Software without restriction, including without limitation the rights
12
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
copies of the Software, and to permit persons to whom the Software is
14
furnished to do so, subject to the following conditions:
16
The above copyright notice and this permission notice shall be included in
17
all copies or substantial portions of the Software.
19
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
26
-----------------------------------------------------------------------------
29
28
#include "OgreD3D9Device.h"
54
53
mFocusWindow = NULL;
55
54
mBehaviorFlags = behaviorFlags;
56
55
mD3D9DeviceCapsValid = false;
57
57
mPresentationParamsCount = 0;
58
mPresentationParams = NULL;
59
mDeviceInvalidated = false;
58
mPresentationParams = NULL;
61
59
memset(&mD3D9DeviceCaps, 0, sizeof(mD3D9DeviceCaps));
62
60
memset(&mCreationParams, 0, sizeof(mCreationParams));
94
92
RenderWindowResources* renderWindowResources = new RenderWindowResources;
96
memset(renderWindowResources, 0, sizeof(RenderWindowResources));
94
memset(renderWindowResources, 0, sizeof(RenderWindowResources));
98
95
renderWindowResources->adapterOrdinalInGroupIndex = 0;
99
mMapRenderWindowToResoruces[renderWindow] = renderWindowResources;
101
// invalidate this device.
96
renderWindowResources->acquired = false;
97
mMapRenderWindowToResoruces[renderWindow] = renderWindowResources;
104
99
updateRenderWindowsIndices();
137
132
bool D3D9Device::acquire()
139
134
updatePresentationParameters();
136
bool resetDevice = false;
141
138
// Create device if need to.
142
139
if (mpDevice == NULL)
144
141
createD3D9Device();
144
// Case device already exists.
147
RenderWindowToResorucesIterator itPrimary = getRenderWindowIterator(getPrimaryWindow());
149
if (itPrimary->second->swapChain != NULL)
151
D3DPRESENT_PARAMETERS currentPresentParams;
154
hr = itPrimary->second->swapChain->GetPresentParameters(¤tPresentParams);
157
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
158
"GetPresentParameters failed",
159
"D3D9RenderWindow::acquire");
162
// Desired parameters are different then current parameters.
163
// Possible scenario is that primary window resized and in the mean while another
164
// window attached to this device.
165
if (memcmp(¤tPresentParams, &mPresentationParams[0], sizeof(D3DPRESENT_PARAMETERS)) != 0)
171
// Make sure depth stencil is set to valid surface. It is going to be
172
// grabbed by the primary window using the GetDepthStencilSurface method.
173
if (resetDevice == false)
175
mpDevice->SetDepthStencilSurface(itPrimary->second->depthBuffer);
147
// Update resources of each window.
148
RenderWindowToResorucesIterator it = mMapRenderWindowToResoruces.begin();
150
while (it != mMapRenderWindowToResoruces.end())
152
acquireRenderWindowResources(it);
180
// Reset device will update all render window resources.
186
// No need to reset -> just acquire resources.
189
// Update resources of each window.
190
RenderWindowToResorucesIterator it = mMapRenderWindowToResoruces.begin();
192
while (it != mMapRenderWindowToResoruces.end())
194
acquireRenderWindowResources(it);
193
236
//---------------------------------------------------------------------
194
237
void D3D9Device::notifyDeviceLost()
196
// Case this device is already in invalid rendering state.
197
if (mDeviceValid == false)
239
// Case this device is already in lost state.
200
// Case we just moved from valid state to invalid state.
201
mDeviceValid = false;
243
// Case we just moved from valid state to lost state.
203
246
D3D9RenderSystem* renderSystem = static_cast<D3D9RenderSystem*>(Root::getSingleton().getRenderSystem());
307
356
//---------------------------------------------------------------------
308
357
bool D3D9Device::reset()
310
updatePresentationParameters();
312
RenderWindowToResorucesIterator it = mMapRenderWindowToResoruces.begin();
314
while (it != mMapRenderWindowToResoruces.end())
316
RenderWindowResources* renderWindowResources = it->second;
318
releaseRenderWindowResources(renderWindowResources);
322
clearDeviceStreams();
328
361
// Check that device is in valid state for reset.
329
362
hr = mpDevice->TestCooperativeLevel();
330
363
if (hr == D3DERR_DEVICELOST ||
369
// Lock access to rendering device.
370
D3D9RenderSystem::getResourceManager()->lockDeviceAccess();
336
372
D3D9RenderSystem* renderSystem = static_cast<D3D9RenderSystem*>(Root::getSingleton().getRenderSystem());
374
// Inform all resources that device lost.
375
D3D9RenderSystem::getResourceManager()->notifyOnDeviceLost(mpDevice);
339
378
// Release all automatic temporary buffers and free unused
340
379
// temporary buffers, so we doesn't need to recreate them,
347
386
// Cleanup depth stencils surfaces.
348
387
renderSystem->_cleanupDepthStencils(mpDevice);
352
// Inform all resources that device lost.
353
D3D9RenderSystem::getResourceManager()->notifyOnDeviceLost(mpDevice);
389
updatePresentationParameters();
391
RenderWindowToResorucesIterator it = mMapRenderWindowToResoruces.begin();
393
while (it != mMapRenderWindowToResoruces.end())
395
RenderWindowResources* renderWindowResources = it->second;
397
releaseRenderWindowResources(renderWindowResources);
401
clearDeviceStreams();
356
404
// Reset the device using the presentation parameters.
357
405
hr = mpDevice->Reset(mPresentationParams);
359
407
if (hr == D3DERR_DEVICELOST)
409
// UnLock access to rendering device.
410
D3D9RenderSystem::getResourceManager()->unlockDeviceAccess();
361
412
// Don't continue
382
432
acquireRenderWindowResources(it);
436
D3D9Device* pCurActiveDevice = mpDeviceManager->getActiveDevice();
438
mpDeviceManager->setActiveDevice(this);
386
440
// Inform all resources that device has been reset.
387
441
D3D9RenderSystem::getResourceManager()->notifyOnDeviceReset(mpDevice);
443
mpDeviceManager->setActiveDevice(pCurActiveDevice);
390
445
renderSystem->notifyOnDeviceReset(this);
447
// UnLock access to rendering device.
448
D3D9RenderSystem::getResourceManager()->unlockDeviceAccess();
404
462
if(primaryPresentationParams.BackBufferHeight != mPresentationParams[i].BackBufferHeight ||
405
463
primaryPresentationParams.BackBufferWidth != mPresentationParams[i].BackBufferWidth ||
406
464
primaryPresentationParams.BackBufferFormat != mPresentationParams[i].BackBufferFormat ||
407
primaryPresentationParams.AutoDepthStencilFormat != mPresentationParams[i].AutoDepthStencilFormat)
465
primaryPresentationParams.AutoDepthStencilFormat != mPresentationParams[i].AutoDepthStencilFormat ||
466
primaryPresentationParams.MultiSampleQuality != mPresentationParams[i].MultiSampleQuality ||
467
primaryPresentationParams.MultiSampleType != mPresentationParams[i].MultiSampleType)
531
591
//---------------------------------------------------------------------
532
592
void D3D9Device::clearDeviceStreams()
594
D3D9RenderSystem* renderSystem = static_cast<D3D9RenderSystem*>(Root::getSingleton().getRenderSystem());
534
596
// Set all texture units to nothing to release texture surfaces
535
597
for (DWORD stage = 0; stage < mD3D9DeviceCaps.MaxSimultaneousTextures; ++stage)
537
mpDevice->SetTexture(stage, NULL);
599
DWORD dwCurValue = D3DTOP_FORCE_DWORD;
602
hr = mpDevice->SetTexture(stage, NULL);
605
String str = "Unable to disable texture '" + StringConverter::toString(stage) + "' in D3D9";
606
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, str, "D3D9Device::clearDeviceStreams" );
609
mpDevice->GetTextureStageState(static_cast<DWORD>(stage), D3DTSS_COLOROP, &dwCurValue);
611
if (dwCurValue != D3DTOP_DISABLE)
613
hr = mpDevice->SetTextureStageState(static_cast<DWORD>(stage), D3DTSS_COLOROP, D3DTOP_DISABLE);
616
String str = "Unable to disable texture '" + StringConverter::toString(stage) + "' in D3D9";
617
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, str, "D3D9Device::clearDeviceStreams" );
622
// set stage desc. to defaults
623
renderSystem->mTexStageDesc[stage].pTex = 0;
624
renderSystem->mTexStageDesc[stage].autoTexCoordType = TEXCALC_NONE;
625
renderSystem->mTexStageDesc[stage].coordIndex = 0;
626
renderSystem->mTexStageDesc[stage].texType = D3D9Mappings::D3D_TEX_TYPE_NORMAL;
540
629
// Unbind any vertex streams to avoid memory leaks
638
727
mD3D9DeviceCapsValid = true;
729
// Initialize device states.
732
// Lock access to rendering device.
733
D3D9RenderSystem::getResourceManager()->lockDeviceAccess();
735
D3D9Device* pCurActiveDevice = mpDeviceManager->getActiveDevice();
737
mpDeviceManager->setActiveDevice(this);
641
739
// Inform all resources that new device created.
642
740
D3D9RenderSystem::getResourceManager()->notifyOnDeviceCreate(mpDevice);
644
// Initialize device states.
742
mpDeviceManager->setActiveDevice(pCurActiveDevice);
744
// UnLock access to rendering device.
745
D3D9RenderSystem::getResourceManager()->unlockDeviceAccess();
648
748
//---------------------------------------------------------------------
651
751
if (mpDevice != NULL)
753
// Lock access to rendering device.
754
D3D9RenderSystem::getResourceManager()->lockDeviceAccess();
756
D3D9Device* pCurActiveDevice = mpDeviceManager->getActiveDevice();
758
mpDeviceManager->setActiveDevice(this);
653
760
// Inform all resources that device is going to be destroyed.
654
761
D3D9RenderSystem::getResourceManager()->notifyOnDeviceDestroy(mpDevice);
656
clearDeviceStreams();
763
mpDeviceManager->setActiveDevice(pCurActiveDevice);
765
clearDeviceStreams();
658
767
// Release device.
659
768
SAFE_RELEASE(mpDevice);
770
// UnLock access to rendering device.
771
D3D9RenderSystem::getResourceManager()->unlockDeviceAccess();
666
778
SAFE_RELEASE(renderWindowResources->backBuffer);
667
779
SAFE_RELEASE(renderWindowResources->depthBuffer);
668
780
SAFE_RELEASE(renderWindowResources->swapChain);
781
renderWindowResources->acquired = false;
671
784
//---------------------------------------------------------------------
672
void D3D9Device::invalidate()
785
void D3D9Device::invalidate(D3D9RenderWindow* renderWindow)
674
mDeviceInvalidated = true;
787
RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
789
it->second->acquired = false;
677
792
//---------------------------------------------------------------------
678
793
bool D3D9Device::validate(D3D9RenderWindow* renderWindow)
795
// Validate that the render window should run on this device.
796
if (false == validateDisplayMonitor(renderWindow))
680
799
// Validate that this device created on the correct target focus window handle
681
800
validateFocusWindow();
683
802
// Validate that the render window dimensions matches to back buffer dimensions.
684
803
validateBackBufferSize(renderWindow);
686
// Validate that the render window should run on this device.
687
if (false == validateDisplayMonitor(renderWindow))
690
805
// Validate that this device is in valid rendering state.
691
806
if (false == validateDeviceState(renderWindow))
697
812
//---------------------------------------------------------------------
698
813
void D3D9Device::validateFocusWindow()
815
// Focus window changed -> device should be re-acquired.
700
816
if ((msSharedFocusWindow != NULL && mCreationParams.hFocusWindow != msSharedFocusWindow) ||
701
817
(msSharedFocusWindow == NULL && mCreationParams.hFocusWindow != getPrimaryWindow()->getWindowHandle()))
819
// Lock access to rendering device.
820
D3D9RenderSystem::getResourceManager()->lockDeviceAccess();
825
// UnLock access to rendering device.
826
D3D9RenderSystem::getResourceManager()->unlockDeviceAccess();
708
830
//---------------------------------------------------------------------
709
831
bool D3D9Device::validateDeviceState(D3D9RenderWindow* renderWindow)
833
RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
834
RenderWindowResources* renderWindowResources = it->second;
713
837
hr = mpDevice->TestCooperativeLevel();
715
839
// Case device is not valid for rendering.
716
if (mDeviceInvalidated || FAILED(hr))
718
RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
719
RenderWindowResources* renderWindowResources = it->second;
721
842
// device lost, and we can't reset
722
843
// can't do anything about it here, wait until we get
723
844
// D3DERR_DEVICENOTRESET; rendering calls will silently fail until
724
845
// then (except Present, but we ignore device lost there too)
725
846
if (hr == D3DERR_DEVICELOST)
727
SAFE_RELEASE(renderWindowResources->backBuffer);
728
SAFE_RELEASE (renderWindowResources->depthBuffer);
731
mDeviceValid = false;
848
releaseRenderWindowResources(renderWindowResources);
736
853
// device lost, and we can reset
737
else if (hr == D3DERR_DEVICENOTRESET || mDeviceInvalidated)
739
bool deviceRestored = reset();
742
if (deviceRestored == false)
747
mDeviceValid = false;
854
else if (hr == D3DERR_DEVICENOTRESET)
856
bool deviceRestored = reset();
858
// Device was not restored yet.
859
if (deviceRestored == false)
868
// Render window resources explicitly invalidated. (Resize or window mode switch)
869
if (renderWindowResources->acquired == false)
871
if (getPrimaryWindow() == renderWindow)
873
bool deviceRestored = reset();
875
// Device was not restored yet.
876
if (deviceRestored == false)
885
acquire(renderWindow);
799
934
// Case this window changed monitor.
800
935
if (hRenderWindowMonitor != mMonitor)
937
// Lock access to rendering device.
938
D3D9RenderSystem::getResourceManager()->lockDeviceAccess();
802
940
mpDeviceManager->linkRenderWindow(renderWindow);
942
// UnLock access to rendering device.
943
D3D9RenderSystem::getResourceManager()->unlockDeviceAccess();
809
951
//---------------------------------------------------------------------
810
952
void D3D9Device::present(D3D9RenderWindow* renderWindow)
812
if (mDeviceValid == false || isDeviceLost())
954
RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
955
RenderWindowResources* renderWindowResources = it->second;
958
// Skip present while current device state is invalid.
960
renderWindowResources->acquired == false ||
815
RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
816
RenderWindowResources* renderWindowResources = it->second;
819
967
if (isMultihead())
1058
uint targetWidth = renderWindow->getWidth();
1059
uint targetHeight = renderWindow->getHeight();
1061
if (targetWidth == 0)
1064
if (targetHeight == 0)
920
1067
HRESULT hr = mpDevice->CreateDepthStencilSurface(
921
renderWindow->getWidth(), renderWindow->getHeight(),
1068
targetWidth, targetHeight,
922
1069
renderWindowResources->presentParameters.AutoDepthStencilFormat,
923
1070
renderWindowResources->presentParameters.MultiSampleType,
924
1071
renderWindowResources->presentParameters.MultiSampleQuality,