Jelajahi Sumber

DirectX 9 device reset works properly

Marko Pintera 11 tahun lalu
induk
melakukan
e22d917c50

+ 1 - 1
BansheeEditor/Source/DbgEditorWidget2.cpp

@@ -36,7 +36,7 @@ namespace BansheeEngine
 		else
 		else
 		{
 		{
 			//gCoreAccessor().setFullscreen(window, *videoMode);
 			//gCoreAccessor().setFullscreen(window, *videoMode);
-			gCoreAccessor().setFullscreen(gApplication().getPrimaryWindow(), 1680, 1050, 60, 0);
+			gCoreAccessor().setFullscreen(gApplication().getPrimaryWindow(), 1920, 1200, 60, 0);
 		}
 		}
 
 
 		cm_dbg_fullscreen = !cm_dbg_fullscreen;
 		cm_dbg_fullscreen = !cm_dbg_fullscreen;

+ 1 - 1
BansheeEditorExec/BsEditorExec.cpp

@@ -11,7 +11,7 @@ int CALLBACK WinMain(
 	_In_  int nCmdShow
 	_In_  int nCmdShow
 	)
 	)
 {
 {
-	EditorApplication::startUp(RenderSystemPlugin::OpenGL);
+	EditorApplication::startUp(RenderSystemPlugin::DX9);
 	EditorApplication::instance().runMainLoop();
 	EditorApplication::instance().runMainLoop();
 	EditorApplication::shutDown();
 	EditorApplication::shutDown();
 
 

+ 35 - 1
CamelotD3D9Renderer/Include/CmD3D9EventQuery.h

@@ -1,6 +1,7 @@
 #pragma once
 #pragma once
 
 
 #include "CmD3D9Prerequisites.h"
 #include "CmD3D9Prerequisites.h"
+#include "CmD3D9Resource.h"
 #include "CmEventQuery.h"
 #include "CmEventQuery.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
@@ -8,7 +9,7 @@ namespace BansheeEngine
 	/**
 	/**
 	 * @copydoc EventQuery
 	 * @copydoc EventQuery
 	 */
 	 */
-	class CM_D3D9_EXPORT D3D9EventQuery : public EventQuery
+	class CM_D3D9_EXPORT D3D9EventQuery : public EventQuery, public D3D9Resource
 	{
 	{
 	public:
 	public:
 		D3D9EventQuery();
 		D3D9EventQuery();
@@ -24,7 +25,40 @@ namespace BansheeEngine
 		 */
 		 */
 		virtual bool isReady() const;
 		virtual bool isReady() const;
 
 
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceCreate
+		 */
+		virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device);
+
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceDestroy
+		 */
+		virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device);
+
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceLost
+		 */
+		virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device);
+
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceReset
+		 */
+		virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device);
+
+	private:
+		/**
+		 * @brief	Creates the internal DX9 query.
+		 */
+		void createQuery();
+
+		/**
+		 * @brief	Releases the internal DX9 query.
+		 */
+		void releaseQuery();
+
 	private:
 	private:
+		bool mQueryIssued;
 		IDirect3DQuery9* mQuery;
 		IDirect3DQuery9* mQuery;
+		IDirect3DDevice9* mDevice;
 	};
 	};
 }
 }

+ 12 - 4
CamelotD3D9Renderer/Include/CmD3D9IndexBuffer.h

@@ -26,16 +26,24 @@ namespace BansheeEngine
         /** See HardwareBuffer. */
         /** See HardwareBuffer. */
 		void writeData(UINT32 offset, UINT32 length, const void* source, BufferWriteType writeFlags = BufferWriteType::Normal);
 		void writeData(UINT32 offset, UINT32 length, const void* source, BufferWriteType writeFlags = BufferWriteType::Normal);
 
 
-		// Called immediately after the Direct3D device has been created.
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceCreate
+		 */
 		virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device);
 		virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device);
 
 
-		// Called before the Direct3D device is going to be destroyed.
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceDestroy
+		 */
 		virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device);
 		virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device);
 
 
-		// Called immediately after the Direct3D device has entered a lost state.
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceLost
+		 */
 		virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device);
 		virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device);
 
 
-		// Called immediately after the Direct3D device has been reset
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceReset
+		 */
 		virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device);
 		virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device);
 
 
 		// Create the actual index buffer.
 		// Create the actual index buffer.

+ 39 - 3
CamelotD3D9Renderer/Include/CmD3D9OcclusionQuery.h

@@ -1,6 +1,7 @@
 #pragma once
 #pragma once
 
 
 #include "CmD3D9Prerequisites.h"
 #include "CmD3D9Prerequisites.h"
+#include "CmD3D9Resource.h"
 #include "CmOcclusionQuery.h"
 #include "CmOcclusionQuery.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
@@ -8,7 +9,7 @@ namespace BansheeEngine
 	/**
 	/**
 	* @copydoc OcclusionQuery
 	* @copydoc OcclusionQuery
 	*/
 	*/
-	class CM_D3D9_EXPORT D3D9OcclusionQuery : public OcclusionQuery
+	class CM_D3D9_EXPORT D3D9OcclusionQuery : public OcclusionQuery, public D3D9Resource
 	{
 	{
 	public:
 	public:
 		D3D9OcclusionQuery(bool binary);
 		D3D9OcclusionQuery(bool binary);
@@ -34,14 +35,49 @@ namespace BansheeEngine
 		*/
 		*/
 		virtual UINT32 getNumFragments();
 		virtual UINT32 getNumFragments();
 
 
+		/**
+		* @copydoc	D3D9Resource::notifyOnDeviceCreate
+		*/
+		virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device);
+
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceDestroy
+		 */
+		virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device);
+
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceLost
+		 */
+		virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device);
+
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceReset
+		 */
+		virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device);
+
 	private:
 	private:
 		friend class QueryManager;
 		friend class QueryManager;
 
 
+		/**
+		 * @brief	Creates the internal DX9 query.
+		 */
+		void createQuery();
+
+		/**
+		 * @brief	Releases the internal DX9 query.
+		 */
+		void releaseQuery();
+
+		/**
+		 * @brief	Resolves query results after it is ready.
+		 */
+		void finalize();
+	private:
+		IDirect3DDevice9* mDevice;
 		IDirect3DQuery9* mQuery;
 		IDirect3DQuery9* mQuery;
+		bool mQueryIssued;
 		bool mFinalized;
 		bool mFinalized;
 
 
 		UINT32 mNumFragments;
 		UINT32 mNumFragments;
-
-		void finalize();
 	};
 	};
 }
 }

+ 33 - 1
CamelotD3D9Renderer/Include/CmD3D9RenderTexture.h

@@ -1,12 +1,13 @@
 #pragma once
 #pragma once
 
 
 #include "CmD3D9Prerequisites.h"
 #include "CmD3D9Prerequisites.h"
+#include "CmD3D9Resource.h"
 #include "CmRenderTexture.h"
 #include "CmRenderTexture.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
 	/// RenderTexture implementation for D3D9
 	/// RenderTexture implementation for D3D9
-	class CM_D3D9_EXPORT D3D9RenderTexture : public RenderTexture
+	class CM_D3D9_EXPORT D3D9RenderTexture : public RenderTexture, public D3D9Resource
 	{
 	{
 	public:
 	public:
 		virtual ~D3D9RenderTexture();
 		virtual ~D3D9RenderTexture();
@@ -14,6 +15,26 @@ namespace BansheeEngine
 		bool requiresTextureFlipping() const { return false; }
 		bool requiresTextureFlipping() const { return false; }
 		virtual void getCustomAttribute(const String& name, void* pData) const;
 		virtual void getCustomAttribute(const String& name, void* pData) const;
 
 
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceCreate
+		 */
+		virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device);
+
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceDestroy
+		 */
+		virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device);
+
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceLost
+		 */
+		virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device);
+
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceReset
+		 */
+		virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device);
+
 	protected:
 	protected:
 		friend class D3D9TextureManager;
 		friend class D3D9TextureManager;
 
 
@@ -24,6 +45,17 @@ namespace BansheeEngine
 		 */
 		 */
 		void initialize_internal();
 		void initialize_internal();
 
 
+		/**
+		 * @brief	Initializes the internal color and depth surfaces.
+		 */
+		void initializeSurfaces();
+
+		/**
+		 * @brief	Releases the internal color and depth surfaces.
+		 */
+		void releaseSurfaces();
+
+	protected:
 		IDirect3DSurface9* mDX9ColorSurface;
 		IDirect3DSurface9* mDX9ColorSurface;
 		IDirect3DSurface9* mDX9DepthStencilSurface;
 		IDirect3DSurface9* mDX9DepthStencilSurface;
 		bool mIsBindableToShader;
 		bool mIsBindableToShader;

+ 1 - 7
CamelotD3D9Renderer/Include/CmD3D9RenderWindow.h

@@ -110,11 +110,6 @@ namespace BansheeEngine
 		 * @brief	Accessor for render surface.
 		 * @brief	Accessor for render surface.
 		 */
 		 */
 		IDirect3DSurface9* _getRenderSurface() const;
 		IDirect3DSurface9* _getRenderSurface() const;
-
-		/**
-		 * @brief	Indicate that fullscreen / windowed switching has finished.
-		 */
-		void _finishSwitchingFullscreen();
 	
 	
 		/**
 		/**
 		 * @brief	Returns true if this window use depth buffer.
 		 * @brief	Returns true if this window use depth buffer.
@@ -152,8 +147,7 @@ namespace BansheeEngine
 		bool						mDeviceValid;			// Device was validation succeeded.
 		bool						mDeviceValid;			// Device was validation succeeded.
 		HWND						mHWnd;					// Win32 Window handle		
 		HWND						mHWnd;					// Win32 Window handle		
 		bool						mIsExternal;			// window not created by Ogre
 		bool						mIsExternal;			// window not created by Ogre
-		bool						mClosed;				// Is this window destroyed.		
-		bool						mSwitchingFullscreen;	// Are we switching from fullscreen to windowed or vice versa		
+		bool						mClosed;				// Is this window destroyed.			
 		D3DMULTISAMPLE_TYPE			mFSAAType;				// AA type.
 		D3DMULTISAMPLE_TYPE			mFSAAType;				// AA type.
 		DWORD						mFSAAQuality;			// AA quality.
 		DWORD						mFSAAQuality;			// AA quality.
 		UINT						mDisplayFrequency;		// Display frequency.
 		UINT						mDisplayFrequency;		// Display frequency.

+ 26 - 17
CamelotD3D9Renderer/Include/CmD3D9Resource.h

@@ -2,39 +2,48 @@
 
 
 #include "CmD3D9Prerequisites.h"
 #include "CmD3D9Prerequisites.h"
 
 
-namespace BansheeEngine {
-
-	/** Represents a Direct3D rendering resource.
-	Provide unified interface to
-	handle various device states.
-	*/
+namespace BansheeEngine 
+{
+	/**
+	 * @brief	Provides an interface for dealing with DX9 resources. Primarily
+	 *			notifying the resources of any changed states.
+	 */
 	class CM_D3D9_EXPORT D3D9Resource
 	class CM_D3D9_EXPORT D3D9Resource
 	{
 	{
-	// Interface.
 	public:
 	public:
 		D3D9Resource();
 		D3D9Resource();
 		virtual ~D3D9Resource();
 		virtual ~D3D9Resource();
 
 
-		// Called immediately after the Direct3D device has been created.
+		/**
+		 * @brief	Called immediately after the Direct3D device has been created.
+		 */
 		virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) {}
 		virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) {}
 
 
-		// Called before the Direct3D device is going to be destroyed.
+		/**
+		 * @brief	Called before the Direct3D device is going to be destroyed.
+		 */
 		virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) {}
 		virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) {}
 
 
-		// Called immediately after the Direct3D device has entered a lost state.
-		// This is the place to release non-managed resources.
+		/**
+		 * @brief	Called immediately after the Direct3D device has entered a lost state.
+		 */
 		virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device) {}
 		virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device) {}
 
 
-		// Called immediately after the Direct3D device has been reset.
-		// This is the place to create non-managed resources.
+		/**
+		 * @brief	Called immediately after the Direct3D device has been reset.
+		 */
 		virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device) {}
 		virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device) {}
 
 
-		// Called when device state is changing. Access to any device should be locked.
-		// Relevant for multi thread application.
+		/**
+		 * @brief	Called when device state is changing. Access to any device should be locked.
+		 *			Relevant for multi thread application.
+		 */
 		static void lockDeviceAccess();
 		static void lockDeviceAccess();
 
 
-		// Called when device state change completed. Access to any device is allowed.
-		// Relevant for multi thread application.
+		/**
+		 * @brief	Called when device state change completed. Access to any device is allowed.
+		 *			Relevant for multi thread application.
+		 */
 		static void unlockDeviceAccess();
 		static void unlockDeviceAccess();
 
 
 	protected:
 	protected:

+ 13 - 5
CamelotD3D9Renderer/Include/CmD3D9Texture.h

@@ -69,17 +69,25 @@ namespace BansheeEngine
 		*/
 		*/
 		PixelBufferPtr getBuffer(UINT32 face, UINT32 mipmap);
 		PixelBufferPtr getBuffer(UINT32 face, UINT32 mipmap);
 
 
-		// Called immediately after the Direct3D device has been created.
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceCreate
+		 */
 		virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device);
 		virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device);
 
 
-		// Called before the Direct3D device is going to be destroyed.
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceDestroy
+		 */
 		virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device);
 		virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device);
 
 
-		// Called immediately after the Direct3D device has entered a lost state.
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceLost
+		 */
 		virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device);
 		virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device);
 
 
-		// Called immediately after the Direct3D device has been reset
-		virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device);	
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceReset
+		 */
+		virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device);
 
 
 	protected:	
 	protected:	
 		friend class D3D9TextureManager;
 		friend class D3D9TextureManager;

+ 45 - 3
CamelotD3D9Renderer/Include/CmD3D9TimerQuery.h

@@ -1,6 +1,7 @@
 #pragma once
 #pragma once
 
 
 #include "CmD3D9Prerequisites.h"
 #include "CmD3D9Prerequisites.h"
+#include "CmD3D9Resource.h"
 #include "CmTimerQuery.h"
 #include "CmTimerQuery.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
@@ -8,7 +9,7 @@ namespace BansheeEngine
 	/**
 	/**
 	 * @copydoc TimerQuery
 	 * @copydoc TimerQuery
 	 */
 	 */
-	class CM_D3D9_EXPORT D3D9TimerQuery : public TimerQuery
+	class CM_D3D9_EXPORT D3D9TimerQuery : public TimerQuery, public D3D9Resource
 	{
 	{
 	public:
 	public:
 		D3D9TimerQuery();
 		D3D9TimerQuery();
@@ -34,15 +35,56 @@ namespace BansheeEngine
 		 */
 		 */
 		virtual float getTimeMs();
 		virtual float getTimeMs();
 
 
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceCreate
+		 */
+		virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device);
+
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceDestroy
+		 */
+		virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device);
+
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceLost
+		 */
+		virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device);
+
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceReset
+		 */
+		virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device);
+
+	private:
+		/**
+		 * @brief	Resolve timing information after the query has finished.
+		 */
+		void finalize();
+
+		/**
+		 * @brief	Creates the internal DX9 query.
+		 */
+		void createQuery();
+
+		/**
+		 * @brief	Releases the internal DX9 query.
+		 */
+		void releaseQuery();
+
+		/**
+		 * @brief	Checks if the internal query object is valid.
+		 */
+		bool isQueryValid() const;
+
 	private:
 	private:
 		bool mFinalized;
 		bool mFinalized;
+		bool mQueryIssued;
 		float mTimeDelta;
 		float mTimeDelta;
 
 
+		IDirect3DDevice9* mDevice;
 		IDirect3DQuery9* mBeginQuery;
 		IDirect3DQuery9* mBeginQuery;
 		IDirect3DQuery9* mEndQuery;
 		IDirect3DQuery9* mEndQuery;
 		IDirect3DQuery9* mDisjointQuery;
 		IDirect3DQuery9* mDisjointQuery;
 		IDirect3DQuery9* mFreqQuery;
 		IDirect3DQuery9* mFreqQuery;
-
-		void finalize();
 	};
 	};
 }
 }

+ 12 - 4
CamelotD3D9Renderer/Include/CmD3D9VertexBuffer.h

@@ -26,16 +26,24 @@ namespace BansheeEngine
         /** See HardwareBuffer. */
         /** See HardwareBuffer. */
         void writeData(UINT32 offset, UINT32 length, const void* source, BufferWriteType writeFlags = BufferWriteType::Normal);
         void writeData(UINT32 offset, UINT32 length, const void* source, BufferWriteType writeFlags = BufferWriteType::Normal);
 	
 	
-		// Called immediately after the Direct3D device has been created.
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceCreate
+		 */
 		virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device);
 		virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device);
 
 
-		// Called before the Direct3D device is going to be destroyed.
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceDestroy
+		 */
 		virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device);
 		virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device);
 
 
-		// Called immediately after the Direct3D device has entered a lost state.
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceLost
+		 */
 		virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device);
 		virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device);
 
 
-		// Called immediately after the Direct3D device has been reset
+		/**
+		 * @copydoc	D3D9Resource::notifyOnDeviceReset
+		 */
 		virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device);
 		virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device);
 
 
 		// Create the actual vertex buffer.
 		// Create the actual vertex buffer.

+ 48 - 10
CamelotD3D9Renderer/Source/CmD3D9EventQuery.cpp

@@ -1,39 +1,77 @@
 #include "CmD3D9EventQuery.h"
 #include "CmD3D9EventQuery.h"
 #include "CmD3D9RenderSystem.h"
 #include "CmD3D9RenderSystem.h"
+#include "CmD3D9ResourceManager.h"
 #include "CmD3D9Device.h"
 #include "CmD3D9Device.h"
 #include "CmException.h"
 #include "CmException.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
 	D3D9EventQuery::D3D9EventQuery()
 	D3D9EventQuery::D3D9EventQuery()
-		:mQuery(nullptr)
+		:mQuery(nullptr), mDevice(nullptr), mQueryIssued(false)
 	{
 	{
-		IDirect3DDevice9* device = D3D9RenderSystem::getActiveD3D9Device();
-		HRESULT hr = device->CreateQuery(D3DQUERYTYPE_EVENT, &mQuery);
+		createQuery();
+	}
+
+	D3D9EventQuery::~D3D9EventQuery()
+	{
+		releaseQuery();
+	}
+
+	void D3D9EventQuery::createQuery()
+	{
+		mDevice = D3D9RenderSystem::getActiveD3D9Device();
 
 
-		if(hr != S_OK)
+		HRESULT hr = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &mQuery);
+		if (hr != S_OK)
 		{
 		{
 			CM_EXCEPT(RenderingAPIException, "Failed to create an Event query.");
 			CM_EXCEPT(RenderingAPIException, "Failed to create an Event query.");
 		}
 		}
 	}
 	}
 
 
-	D3D9EventQuery::~D3D9EventQuery()
+	void D3D9EventQuery::releaseQuery()
 	{
 	{
-		if(mQuery != nullptr)
-		{
-			mQuery->Release();
-		}
+		SAFE_RELEASE(mQuery);
 	}
 	}
 
 
 	void D3D9EventQuery::begin()
 	void D3D9EventQuery::begin()
 	{
 	{
-		mQuery->Issue(D3DISSUE_END);
+		if (mQuery != nullptr)
+			mQuery->Issue(D3DISSUE_END);
+
 		setActive(true);
 		setActive(true);
+		mQueryIssued = true;
 	}
 	}
 
 
 	bool D3D9EventQuery::isReady() const
 	bool D3D9EventQuery::isReady() const
 	{
 	{
+		if (mQuery == nullptr) // Possibly device reset, in which case query is done
+			return mQueryIssued;
+
 		BOOL queryData;
 		BOOL queryData;
 		return mQuery->GetData(&queryData, sizeof(BOOL), 0) == S_OK;
 		return mQuery->GetData(&queryData, sizeof(BOOL), 0) == S_OK;
 	}
 	}
+
+	void D3D9EventQuery::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device)
+	{
+		if (d3d9Device == mDevice)
+			createQuery();
+	}
+
+	void D3D9EventQuery::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device)
+	{
+		if (d3d9Device == mDevice)
+			releaseQuery();
+	}
+
+	void D3D9EventQuery::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device)
+	{
+		if (d3d9Device == mDevice)
+			releaseQuery();
+	}
+
+	void D3D9EventQuery::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device)
+	{
+		if (d3d9Device == mDevice)
+			createQuery();
+	}
 }
 }

+ 57 - 8
CamelotD3D9Renderer/Source/CmD3D9OcclusionQuery.cpp

@@ -5,38 +5,57 @@
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
 	D3D9OcclusionQuery::D3D9OcclusionQuery(bool binary)
 	D3D9OcclusionQuery::D3D9OcclusionQuery(bool binary)
-		:OcclusionQuery(binary), mQuery(nullptr), mNumFragments(0), mFinalized(false)
+		:OcclusionQuery(binary), mQuery(nullptr), mNumFragments(0), 
+		mFinalized(false), mDevice(nullptr), mQueryIssued(false)
 	{
 	{
-		IDirect3DDevice9* device = D3D9RenderSystem::getActiveD3D9Device();
+		createQuery();
+	}
+
+	D3D9OcclusionQuery::~D3D9OcclusionQuery()
+	{
+		releaseQuery();
+	}
+
+	void D3D9OcclusionQuery::createQuery()
+	{
+		mDevice = D3D9RenderSystem::getActiveD3D9Device();
 
 
-		HRESULT hr = device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery);
+		HRESULT hr = mDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery);
 		if (hr != S_OK)
 		if (hr != S_OK)
 		{
 		{
 			CM_EXCEPT(RenderingAPIException, "Failed to create an occlusion query.");
 			CM_EXCEPT(RenderingAPIException, "Failed to create an occlusion query.");
 		}
 		}
 	}
 	}
 
 
-	D3D9OcclusionQuery::~D3D9OcclusionQuery()
+	void D3D9OcclusionQuery::releaseQuery()
 	{
 	{
-		if (mQuery != nullptr)
-			mQuery->Release();
+		SAFE_RELEASE(mQuery);
 	}
 	}
 
 
 	void D3D9OcclusionQuery::begin()
 	void D3D9OcclusionQuery::begin()
 	{
 	{
-		mQuery->Issue(D3DISSUE_BEGIN);
+		if (mQuery != nullptr)
+			mQuery->Issue(D3DISSUE_BEGIN);
 
 
 		mNumFragments = 0;
 		mNumFragments = 0;
+		mQueryIssued = false;
 		setActive(true);
 		setActive(true);
 	}
 	}
 
 
 	void D3D9OcclusionQuery::end()
 	void D3D9OcclusionQuery::end()
 	{
 	{
-		mQuery->Issue(D3DISSUE_END);
+		if (mQuery != nullptr)
+			mQuery->Issue(D3DISSUE_END);
+
+		mQueryIssued = true;
+		mFinalized = false;
 	}
 	}
 
 
 	bool D3D9OcclusionQuery::isReady() const
 	bool D3D9OcclusionQuery::isReady() const
 	{
 	{
+		if (mQuery == nullptr)
+			return mQueryIssued; // If we lost the query, return as ready if it was ever issued
+
 		BOOL queryData;
 		BOOL queryData;
 		return mQuery->GetData(&queryData, sizeof(BOOL), 0) == S_OK;
 		return mQuery->GetData(&queryData, sizeof(BOOL), 0) == S_OK;
 	}
 	}
@@ -55,9 +74,39 @@ namespace BansheeEngine
 	{
 	{
 		mFinalized = true;
 		mFinalized = true;
 
 
+		if (mQuery == nullptr)
+		{
+			mNumFragments = 0;
+			return;
+		}
+
 		DWORD numFragments;
 		DWORD numFragments;
 		mQuery->GetData(&numFragments, sizeof(DWORD), 0);
 		mQuery->GetData(&numFragments, sizeof(DWORD), 0);
 
 
 		mNumFragments = (UINT32)numFragments;
 		mNumFragments = (UINT32)numFragments;
 	}
 	}
+
+	void D3D9OcclusionQuery::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device)
+	{
+		if (d3d9Device == mDevice)
+			createQuery();
+	}
+
+	void D3D9OcclusionQuery::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device)
+	{
+		if (d3d9Device == mDevice)
+			releaseQuery();
+	}
+
+	void D3D9OcclusionQuery::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device)
+	{
+		if (d3d9Device == mDevice)
+			releaseQuery();
+	}
+
+	void D3D9OcclusionQuery::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device)
+	{
+		if (d3d9Device == mDevice)
+			createQuery();
+	}
 }
 }

+ 8 - 7
CamelotD3D9Renderer/Source/CmD3D9RenderSystem.cpp

@@ -555,7 +555,8 @@ namespace BansheeEngine
 		setTextureFiltering(unit, FT_MIP, state->getTextureFiltering(FT_MIP));
 		setTextureFiltering(unit, FT_MIP, state->getTextureFiltering(FT_MIP));
 
 
 		// Set texture layer filtering
 		// Set texture layer filtering
-		setTextureAnisotropy(unit, state->getTextureAnisotropy());
+		if (state->getTextureAnisotropy() > 0)
+			setTextureAnisotropy(unit, state->getTextureAnisotropy());
 
 
 		// Set mipmap biasing
 		// Set mipmap biasing
 		setTextureMipmapBias(unit, state->getTextureMipmapBias());
 		setTextureMipmapBias(unit, state->getTextureMipmapBias());
@@ -1401,14 +1402,14 @@ namespace BansheeEngine
 		if(!clearEntireTarget)
 		if(!clearEntireTarget)
 		{
 		{
 			D3DRECT clearD3DRect;
 			D3DRECT clearD3DRect;
-			clearD3DRect.x1 = clearRect.x;
-			clearD3DRect.x2 = clearD3DRect.x1 + clearRect.width;
+			clearD3DRect.x1 = (LONG)Math::clamp(clearRect.x, 0, (INT32)mActiveRenderTarget->getWidth() - 1);
+			clearD3DRect.x2 = (LONG)Math::clamp((INT32)clearD3DRect.x1 + clearRect.width, 0, (INT32)mActiveRenderTarget->getWidth() - 1);
 
 
-			clearD3DRect.y1 = clearRect.y;
-			clearD3DRect.y2 = clearD3DRect.y1 + clearRect.height;
+			clearD3DRect.y1 = (LONG)Math::clamp(clearRect.y, 0, (INT32)mActiveRenderTarget->getHeight() - 1);
+			clearD3DRect.y2 = (LONG)Math::clamp((INT32)clearD3DRect.y1 + clearRect.height, 0, (INT32)mActiveRenderTarget->getHeight() - 1);
 
 
 			HRESULT hr;
 			HRESULT hr;
-			if(FAILED( hr = getActiveD3D9Device()->Clear(1, &clearD3DRect, flags, color.getAsBGRA(), depth, stencil)))
+			if(FAILED(hr = getActiveD3D9Device()->Clear(1, &clearD3DRect, flags, color.getAsBGRA(), depth, stencil)))
 			{
 			{
 				String msg = DXGetErrorDescription(hr);
 				String msg = DXGetErrorDescription(hr);
 				CM_EXCEPT(RenderingAPIException, "Error clearing frame buffer : " + msg);
 				CM_EXCEPT(RenderingAPIException, "Error clearing frame buffer : " + msg);
@@ -1417,7 +1418,7 @@ namespace BansheeEngine
 		else
 		else
 		{
 		{
 			HRESULT hr;
 			HRESULT hr;
-			if(FAILED( hr = getActiveD3D9Device()->Clear(0, nullptr, flags, color.getAsBGRA(), depth, stencil)))
+			if(FAILED(hr = getActiveD3D9Device()->Clear(0, nullptr, flags, color.getAsBGRA(), depth, stencil)))
 			{
 			{
 				String msg = DXGetErrorDescription(hr);
 				String msg = DXGetErrorDescription(hr);
 				CM_EXCEPT(RenderingAPIException, "Error clearing frame buffer : " + msg);
 				CM_EXCEPT(RenderingAPIException, "Error clearing frame buffer : " + msg);

+ 42 - 10
CamelotD3D9Renderer/Source/CmD3D9RenderTexture.cpp

@@ -17,6 +17,33 @@ namespace BansheeEngine
 
 
 	}
 	}
 
 
+	void D3D9RenderTexture::initialize_internal()
+	{
+		initializeSurfaces();
+
+		RenderTexture::initialize_internal();
+	}
+
+	void D3D9RenderTexture::initializeSurfaces()
+	{
+		D3D9Texture* d3d9texture = static_cast<D3D9Texture*>(mColorSurface->getTexture().get());
+		D3D9PixelBuffer* pixelBuffer = static_cast<D3D9PixelBuffer*>(
+			d3d9texture->getBuffer(mColorSurface->getFirstArraySlice(), mColorSurface->getMostDetailedMip()).get());
+		mDX9ColorSurface = pixelBuffer->getSurface(D3D9RenderSystem::getActiveD3D9Device());
+
+		D3D9Texture* d3d9DepthStencil = static_cast<D3D9Texture*>(mDepthStencilSurface->getTexture().get());
+		D3D9PixelBuffer* depthStencilBuffer = static_cast<D3D9PixelBuffer*>(
+			d3d9DepthStencil->getBuffer(mDepthStencilSurface->getFirstArraySlice(), mDepthStencilSurface->getMostDetailedMip()).get());
+		mDX9DepthStencilSurface = depthStencilBuffer->getSurface(D3D9RenderSystem::getActiveD3D9Device());
+	}
+
+	void D3D9RenderTexture::releaseSurfaces()
+	{
+		// All actual releasing happens in the color and depth textures.
+		mDX9ColorSurface = nullptr;
+		mDX9DepthStencilSurface = nullptr;
+	}
+
 	void D3D9RenderTexture::getCustomAttribute(const String& name, void* pData) const
 	void D3D9RenderTexture::getCustomAttribute(const String& name, void* pData) const
 	{
 	{
 		if(name == "DDBACKBUFFER")
 		if(name == "DDBACKBUFFER")
@@ -39,18 +66,23 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void D3D9RenderTexture::initialize_internal()
+	void D3D9RenderTexture::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device)
 	{
 	{
-		D3D9Texture* d3d9texture = static_cast<D3D9Texture*>(mColorSurface->getTexture().get());
-		D3D9PixelBuffer* pixelBuffer = static_cast<D3D9PixelBuffer*>(
-			d3d9texture->getBuffer(mColorSurface->getFirstArraySlice(), mColorSurface->getMostDetailedMip()).get());
-		mDX9ColorSurface = pixelBuffer->getSurface(D3D9RenderSystem::getActiveD3D9Device());
+		initializeSurfaces();
+	}
 
 
-		D3D9Texture* d3d9DepthStencil = static_cast<D3D9Texture*>(mDepthStencilSurface->getTexture().get());
-		D3D9PixelBuffer* depthStencilBuffer = static_cast<D3D9PixelBuffer*>(
-			d3d9DepthStencil->getBuffer(mDepthStencilSurface->getFirstArraySlice(), mDepthStencilSurface->getMostDetailedMip()).get());
-		mDX9DepthStencilSurface = depthStencilBuffer->getSurface(D3D9RenderSystem::getActiveD3D9Device());
+	void D3D9RenderTexture::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device)
+	{
+		releaseSurfaces();
+	}
 
 
-		RenderTexture::initialize_internal();
+	void D3D9RenderTexture::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device)
+	{
+		releaseSurfaces();
+	}
+
+	void D3D9RenderTexture::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device)
+	{
+		initializeSurfaces();
 	}
 	}
 }
 }

+ 4 - 51
CamelotD3D9Renderer/Source/CmD3D9RenderWindow.cpp

@@ -21,7 +21,6 @@ namespace BansheeEngine
 		mHWnd = 0;
 		mHWnd = 0;
 		mActive = false;		
 		mActive = false;		
 		mClosed = false;
 		mClosed = false;
-		mSwitchingFullscreen = false;
 		mDisplayFrequency = 0;
 		mDisplayFrequency = 0;
 		mDeviceValid = false;
 		mDeviceValid = false;
 	}
 	}
@@ -276,7 +275,6 @@ namespace BansheeEngine
 		mDisplayFrequency = Math::roundToInt(refreshRate);
 		mDisplayFrequency = Math::roundToInt(refreshRate);
 
 
 		mIsFullScreen = true;
 		mIsFullScreen = true;
-		mSwitchingFullscreen = true;
 
 
 		HMONITOR hMonitor = outputInfo.getMonitorHandle();
 		HMONITOR hMonitor = outputInfo.getMonitorHandle();
 		MONITORINFO monitorInfo;
 		MONITORINFO monitorInfo;
@@ -290,17 +288,18 @@ namespace BansheeEngine
 
 
 		if (oldFullscreen) // Was previously fullscreen, just changing the resolution
 		if (oldFullscreen) // Was previously fullscreen, just changing the resolution
 		{
 		{
-			SetWindowPos(mHWnd, HWND_TOPMOST, mLeft, mTop, mWidth, mHeight, SWP_NOACTIVATE);
+			//SetWindowPos(mHWnd, HWND_TOPMOST, mLeft, mTop, mWidth, mHeight, SWP_NOACTIVATE);
 		}
 		}
 		else
 		else
 		{
 		{
-			SetWindowPos(mHWnd, HWND_TOPMOST, mLeft, mTop, mWidth, mHeight, SWP_NOACTIVATE);
+			//SetWindowPos(mHWnd, HWND_TOPMOST, mLeft, mTop, mWidth, mHeight, SWP_NOACTIVATE);
 			SetWindowLong(mHWnd, GWL_STYLE, mStyle);
 			SetWindowLong(mHWnd, GWL_STYLE, mStyle);
 			SetWindowPos(mHWnd, 0, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
 			SetWindowPos(mHWnd, 0, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
 		}
 		}
 
 
 		// Invalidate device, which resets it
 		// Invalidate device, which resets it
 		mDevice->invalidate(this);
 		mDevice->invalidate(this);
+		mDevice->acquire();
 	}
 	}
 
 
 	void D3D9RenderWindow::setFullscreen(const VideoMode& mode, UINT32 refreshRateIdx)
 	void D3D9RenderWindow::setFullscreen(const VideoMode& mode, UINT32 refreshRateIdx)
@@ -329,7 +328,6 @@ namespace BansheeEngine
 			return;
 			return;
 
 
 		mIsFullScreen = false;
 		mIsFullScreen = false;
-		mSwitchingFullscreen = true;
 
 
 		mStyle = WS_VISIBLE | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW;
 		mStyle = WS_VISIBLE | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW;
 
 
@@ -341,6 +339,7 @@ namespace BansheeEngine
 			SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE);
 			SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE);
 
 
 		mDevice->invalidate(this);
 		mDevice->invalidate(this);
+		mDevice->acquire();
 	}
 	}
 
 
 	void D3D9RenderWindow::setHidden(bool hidden)
 	void D3D9RenderWindow::setHidden(bool hidden)
@@ -526,52 +525,6 @@ namespace BansheeEngine
 			*winHeight = maxH;
 			*winHeight = maxH;
 
 
 	}
 	}
-
-	void D3D9RenderWindow::_finishSwitchingFullscreen()
-	{		
-		if(mIsFullScreen)
-		{
-			// Need to reset the region on the window sometimes, when the 
-			// windowed mode was constrained by desktop 
-			HRGN hRgn = CreateRectRgn(0,0,mWidth, mHeight);
-			SetWindowRgn(mHWnd, hRgn, FALSE);
-		}
-		else
-		{
-			// When switching back to windowed mode, need to reset window size 
-			// after device has been restored
-			// We may have had a resize event which polluted our desired sizes
-			unsigned int winWidth, winHeight;
-			_adjustWindow(mDesiredWidth, mDesiredHeight, mStyle, &winWidth, &winHeight);
-
-			// deal with centreing when switching down to smaller resolution
-
-			HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST);
-			MONITORINFO monitorInfo;
-			memset(&monitorInfo, 0, sizeof(MONITORINFO));
-			monitorInfo.cbSize = sizeof(MONITORINFO);
-			GetMonitorInfo(hMonitor, &monitorInfo);
-
-			LONG screenw = monitorInfo.rcWork.right  - monitorInfo.rcWork.left;
-			LONG screenh = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
-
-
-			int left = screenw > int(winWidth) ? ((screenw - int(winWidth)) / 2) : 0;
-			int top = screenh > int(winHeight) ? ((screenh - int(winHeight)) / 2) : 0;
-			SetWindowPos(mHWnd, HWND_NOTOPMOST, left, top, winWidth, winHeight,
-				SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOACTIVATE);
-
-			if (mWidth != mDesiredWidth ||
-				mHeight != mDesiredHeight)
-			{
-				mWidth = mDesiredWidth;
-				mHeight = mDesiredHeight;
-
-				// TODO - Notify viewports of resize		
-			}
-		}
-		mSwitchingFullscreen = false;
-	}
 	
 	
 	void D3D9RenderWindow::_buildPresentParameters(D3DPRESENT_PARAMETERS* presentParams) const
 	void D3D9RenderWindow::_buildPresentParameters(D3DPRESENT_PARAMETERS* presentParams) const
 	{		
 	{		

+ 83 - 27
CamelotD3D9Renderer/Source/CmD3D9TimerQuery.cpp

@@ -5,67 +5,91 @@
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
 	D3D9TimerQuery::D3D9TimerQuery()
 	D3D9TimerQuery::D3D9TimerQuery()
-		:mFinalized(false), mBeginQuery(nullptr), mFreqQuery(nullptr),
-		mEndQuery(nullptr), mDisjointQuery(nullptr), mTimeDelta(0.0f)
+		:mFinalized(false), mBeginQuery(nullptr), mFreqQuery(nullptr), mQueryIssued(false),
+		mEndQuery(nullptr), mDisjointQuery(nullptr), mTimeDelta(0.0f), mDevice(nullptr)
 	{
 	{
-		IDirect3DDevice9* device = D3D9RenderSystem::getActiveD3D9Device();
+		createQuery();
+	}
+
+	D3D9TimerQuery::~D3D9TimerQuery()
+	{
+		releaseQuery();
+	}
 
 
-		HRESULT hr = device->CreateQuery(D3DQUERYTYPE_TIMESTAMPDISJOINT, &mDisjointQuery);
-		if(hr != S_OK)
+	void D3D9TimerQuery::createQuery()
+	{
+		mDevice = D3D9RenderSystem::getActiveD3D9Device();
+
+		HRESULT hr = mDevice->CreateQuery(D3DQUERYTYPE_TIMESTAMPDISJOINT, &mDisjointQuery);
+		if (hr != S_OK)
 		{
 		{
 			CM_EXCEPT(RenderingAPIException, "Failed to create a timer query.");
 			CM_EXCEPT(RenderingAPIException, "Failed to create a timer query.");
 		}
 		}
 
 
-		hr = device->CreateQuery(D3DQUERYTYPE_TIMESTAMPFREQ, &mFreqQuery);
-		if(hr != S_OK)
+		hr = mDevice->CreateQuery(D3DQUERYTYPE_TIMESTAMPFREQ, &mFreqQuery);
+		if (hr != S_OK)
 		{
 		{
 			CM_EXCEPT(RenderingAPIException, "Failed to create a timer query.");
 			CM_EXCEPT(RenderingAPIException, "Failed to create a timer query.");
 		}
 		}
 
 
-		hr = device->CreateQuery(D3DQUERYTYPE_TIMESTAMP, &mBeginQuery);
-		if(hr != S_OK)
+		hr = mDevice->CreateQuery(D3DQUERYTYPE_TIMESTAMP, &mBeginQuery);
+		if (hr != S_OK)
 		{
 		{
 			CM_EXCEPT(RenderingAPIException, "Failed to create a timer query.");
 			CM_EXCEPT(RenderingAPIException, "Failed to create a timer query.");
 		}
 		}
 
 
-		hr = device->CreateQuery(D3DQUERYTYPE_TIMESTAMP, &mEndQuery);
-		if(hr != S_OK)
+		hr = mDevice->CreateQuery(D3DQUERYTYPE_TIMESTAMP, &mEndQuery);
+		if (hr != S_OK)
 		{
 		{
 			CM_EXCEPT(RenderingAPIException, "Failed to create a timer query.");
 			CM_EXCEPT(RenderingAPIException, "Failed to create a timer query.");
 		}
 		}
 	}
 	}
 
 
-	D3D9TimerQuery::~D3D9TimerQuery()
+	void D3D9TimerQuery::releaseQuery()
 	{
 	{
-		if(mBeginQuery != nullptr)
-			mBeginQuery->Release();
-
-		if(mEndQuery != nullptr)
-			mEndQuery->Release();
-
-		if(mDisjointQuery != nullptr)
-			mDisjointQuery->Release();
+		SAFE_RELEASE(mBeginQuery);
+		SAFE_RELEASE(mEndQuery);
+		SAFE_RELEASE(mDisjointQuery);
+		SAFE_RELEASE(mFreqQuery);
+	}
 
 
-		if(mFreqQuery != nullptr)
-			mFreqQuery->Release();
+	bool D3D9TimerQuery::isQueryValid() const
+	{
+		return mDisjointQuery != nullptr && mBeginQuery != nullptr && 
+			mEndQuery != nullptr && mFreqQuery != nullptr;
 	}
 	}
 
 
 	void D3D9TimerQuery::begin()
 	void D3D9TimerQuery::begin()
 	{
 	{
-		mDisjointQuery->Issue(D3DISSUE_BEGIN);
-		mFreqQuery->Issue(D3DISSUE_END);
-		mBeginQuery->Issue(D3DISSUE_END);
+		mQueryIssued = false;
+
+		if (isQueryValid())
+		{
+			mDisjointQuery->Issue(D3DISSUE_BEGIN);
+			mFreqQuery->Issue(D3DISSUE_END);
+			mBeginQuery->Issue(D3DISSUE_END);
+		}
+
 		setActive(true);
 		setActive(true);
 	}
 	}
 
 
 	void D3D9TimerQuery::end()
 	void D3D9TimerQuery::end()
 	{
 	{
-		mEndQuery->Issue(D3DISSUE_END);
-		mDisjointQuery->Issue(D3DISSUE_END);
+		if (isQueryValid())
+		{
+			mEndQuery->Issue(D3DISSUE_END);
+			mDisjointQuery->Issue(D3DISSUE_END);
+		}
+
+		mQueryIssued = true;
+		mFinalized = false;
 	}
 	}
 
 
 	bool D3D9TimerQuery::isReady() const
 	bool D3D9TimerQuery::isReady() const
 	{
 	{
+		if (!isQueryValid()) // Possibly device reset, in which case query is considered done if issued
+			return mQueryIssued;
+
 		BOOL queryData;
 		BOOL queryData;
 		return mDisjointQuery->GetData(&queryData, sizeof(BOOL), 0) == S_OK;
 		return mDisjointQuery->GetData(&queryData, sizeof(BOOL), 0) == S_OK;
 	}
 	}
@@ -82,6 +106,14 @@ namespace BansheeEngine
 
 
 	void D3D9TimerQuery::finalize()
 	void D3D9TimerQuery::finalize()
 	{
 	{
+		mFinalized = true;
+
+		if (!isQueryValid())
+		{
+			mTimeDelta = 0.0f;
+			return;
+		}
+
 		BOOL disjoint;
 		BOOL disjoint;
 		mDisjointQuery->GetData(&disjoint, sizeof(BOOL), 0);
 		mDisjointQuery->GetData(&disjoint, sizeof(BOOL), 0);
 
 
@@ -102,4 +134,28 @@ namespace BansheeEngine
 			LOGWRN("Unrealiable GPU timer query detected.");
 			LOGWRN("Unrealiable GPU timer query detected.");
 		}
 		}
 	}
 	}
+
+	void D3D9TimerQuery::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device)
+	{
+		if (d3d9Device == mDevice)
+			createQuery();
+	}
+
+	void D3D9TimerQuery::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device)
+	{
+		if (d3d9Device == mDevice)
+			releaseQuery();
+	}
+
+	void D3D9TimerQuery::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device)
+	{
+		if (d3d9Device == mDevice)
+			releaseQuery();
+	}
+
+	void D3D9TimerQuery::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device)
+	{
+		if (d3d9Device == mDevice)
+			createQuery();
+	}
 }
 }

+ 11 - 10
Polish.txt

@@ -15,18 +15,8 @@ Finish GPUProfiler:
 
 
  Fullscreen stuff:
  Fullscreen stuff:
 
 
- In DX9 RenderWindow delete _finishSwitchingFullscreen method if possible after I test fullscreen switching
- Update OpenGL render window set fullscreen methods.
-
-Test if it all works. Especially going fullscreen on another monitor.
 When initializing a render window I don't have an option to use exact refresh rate (i.e. in RENDER_WINDOW_DESC)
 When initializing a render window I don't have an option to use exact refresh rate (i.e. in RENDER_WINDOW_DESC)
 
 
-ChangeDisplaySettingEx - For actually changing resolution and refresh rate
- - http://msdn.microsoft.com/en-us/library/windows/desktop/dd183413(v=vs.85).aspx
-
- 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
-
 Add a better way of specifying FSAA (and don't call it FSAA because it's multisampling)
 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.
  - fsaaHint is useless in most cases. Add an Enum instead.
 
 
@@ -34,6 +24,17 @@ I should be able to specify resolution when going to windowed mode
  - Maybe just store the windowed and fullscreen resolutions separately and restore automatically?
  - Maybe just store the windowed and fullscreen resolutions separately and restore automatically?
 
 
 OpenGL going back from windowed mode doesn't restore window style properly.
 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
+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
+
+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
 
 
  -----------------------------
  -----------------------------