Przeglądaj źródła

Fixes to DX9 device reset

Marko Pintera 11 lat temu
rodzic
commit
f4606177a5

+ 8 - 12
CamelotD3D9Renderer/Include/CmD3D9RenderSystem.h

@@ -157,23 +157,19 @@ namespace BansheeEngine
 		void registerWindow(RenderWindow& renderWindow);
 
 	private:
-		/// Direct3D
-		IDirect3D9*	 mpD3D;		
+		static D3D9RenderSystem* msD3D9RenderSystem;
+
+		IDirect3D9*	mpD3D;
+		bool mIsFrameInProgress;
+		bool mRestoreFrameOnReset;
+
+		mutable D3D9DriverList* mDriverList;
+		D3D9Driver* mActiveD3DDriver;
 
-		/// instance
 		HINSTANCE mhInstance;
 
 		UINT32 mViewportLeft, mViewportTop, mViewportWidth, mViewportHeight;
-		// Scissor test rectangle
 		RECT mScissorRect;
-		/// List of D3D drivers installed (video cards)
-		mutable D3D9DriverList* mDriverList; // TODO - Mutable because it gets constructed in getDirect3DDrivers(). Change that.
-		/// Currently active driver
-		D3D9Driver* mActiveD3DDriver;
-		/// NVPerfHUD allowed?
-		bool mUseNVPerfHUD;
-		/// Fast singleton access.
-		static D3D9RenderSystem* msD3D9RenderSystem;
 
 		DrawOperationType mCurrentDrawOperation;
 

+ 18 - 8
CamelotD3D9Renderer/Source/CmD3D9RenderSystem.cpp

@@ -48,10 +48,9 @@ namespace BansheeEngine
 	D3D9RenderSystem* D3D9RenderSystem::msD3D9RenderSystem = NULL;
 
 	D3D9RenderSystem::D3D9RenderSystem( HINSTANCE hInstance )
-		: mTexStageDesc(nullptr)
-		, mNumTexStages(0)
-		, mCurrentDrawOperation(DOT_TRIANGLE_LIST)
-		, mViewportLeft(0), mViewportTop(0), mViewportWidth(0), mViewportHeight(0)
+		: mTexStageDesc(nullptr), mNumTexStages(0), mCurrentDrawOperation(DOT_TRIANGLE_LIST), 
+		mViewportLeft(0), mViewportTop(0), mViewportWidth(0), mViewportHeight(0),
+		mIsFrameInProgress(false), mRestoreFrameOnReset(false)
 	{
 		// update singleton access pointer.
 		msD3D9RenderSystem = this;
@@ -63,7 +62,6 @@ namespace BansheeEngine
 		mpD3D = NULL;		
 		mDriverList = NULL;
 		mActiveD3DDriver = NULL;	
-		mUseNVPerfHUD = false;
 		mHLSLProgramFactory = NULL;		
 		mDeviceManager = NULL;	
 		mResourceManager = nullptr;	
@@ -1153,14 +1151,14 @@ namespace BansheeEngine
 		THROW_IF_NOT_CORE_THREAD;
 
 		HRESULT hr;
-
-		if( FAILED( hr = getActiveD3D9Device()->BeginScene() ) )
+		if(FAILED(hr = getActiveD3D9Device()->BeginScene()))
 		{
 			String msg = DXGetErrorDescription(hr);
 			CM_EXCEPT(RenderingAPIException, "Error beginning frame :" + msg);
 		}
 
  		mDeviceManager->getActiveDevice()->clearDeviceStreams();
+		mIsFrameInProgress = true;
 	}
 
 	void D3D9RenderSystem::endFrame()
@@ -1170,6 +1168,8 @@ namespace BansheeEngine
 		HRESULT hr;
 		if(FAILED(hr = getActiveD3D9Device()->EndScene()))
 			CM_EXCEPT(RenderingAPIException, "Error ending frame");
+
+		mIsFrameInProgress = false;
 	}
 
 	void D3D9RenderSystem::setVertexDeclaration(VertexDeclarationPtr decl)
@@ -2234,7 +2234,11 @@ namespace BansheeEngine
 
 	void D3D9RenderSystem::notifyOnDeviceLost(D3D9Device* device)
 	{	
-
+		if (mIsFrameInProgress)
+		{
+			endFrame();
+			mRestoreFrameOnReset = true;
+		}
 	}
 
 	void D3D9RenderSystem::notifyOnDeviceReset(D3D9Device* device)
@@ -2242,6 +2246,12 @@ namespace BansheeEngine
 		// Reset state attributes.	
 		mVertexProgramBound = false;
 		mFragmentProgramBound = false;
+
+		if (mRestoreFrameOnReset)
+		{
+			beginFrame();
+			mRestoreFrameOnReset = false;
+		}
 	}
 
 	void D3D9RenderSystem::determineFSAASettings(IDirect3DDevice9* d3d9Device,

+ 0 - 1
CamelotD3D9Renderer/Source/CmD3D9RenderWindow.cpp

@@ -585,7 +585,6 @@ namespace BansheeEngine
 			{
 				presentParams->PresentationInterval = D3DPRESENT_INTERVAL_ONE;
 			}
-
 		}
 		else
 		{

+ 6 - 3
Polish.txt

@@ -16,6 +16,7 @@ Finish GPUProfiler:
  Fullscreen stuff:
 
 When initializing a render window I don't have an option to use exact refresh rate (i.e. in RENDER_WINDOW_DESC)
+ - Likely use a VideoMode you can create manually
 
 Add a better way of specifying FSAA (and don't call it FSAA because it's multisampling)
  - fsaaHint is useless in most cases. Add an Enum instead.
@@ -26,12 +27,14 @@ I should be able to specify resolution when going to windowed mode
 OpenGL going back from windowed mode doesn't restore window style properly.
 OpenGL doesn't list windows in the same order as DirectX
 
-DirectX 9 still crashes when going to fullscreen (presumably only when using retail DX9 runtime)
-Switching from higher to lower resoltuion in DX9 causes an issue where viewport is larger than the render target. 
-Test DirectX 9 full-screen on another monitor
+Switching from higher to lower resoltuion in DX9 causes an issue where viewport is larger than the render target. (Only with debug runtime - Can probably ignore)
+When toggling fullscreen two times device reset fails
 In DX9 render window I have disabled top most style.
   - If needed re-enable it, if not remove it from OpenGL as well as I think it disables alt+tab
 
+DISREGARD MONITOR INDEX ON DX9
+ - It's not trivial and its not worth wasting time on a deprecated system
+
 LATER:
  Add ability to change FSAA on RenderWindow.
   - Maybe later. OpenGL requires window to be re-created for it to change I think. As SetPixelFormat is allowed to be called just once per window