Procházet zdrojové kódy

Vulkan queries WIP

BearishSun před 9 roky
rodič
revize
11c403a10d
26 změnil soubory, kde provedl 354 přidání a 85 odebrání
  1. 6 2
      Source/BansheeCore/Include/BsEventQuery.h
  2. 2 2
      Source/BansheeCore/Include/BsOcclusionQuery.h
  3. 12 4
      Source/BansheeCore/Include/BsTimerQuery.h
  4. 1 1
      Source/BansheeD3D11RenderAPI/Include/BsD3D11EventQuery.h
  5. 2 2
      Source/BansheeD3D11RenderAPI/Include/BsD3D11OcclusionQuery.h
  6. 2 2
      Source/BansheeD3D11RenderAPI/Include/BsD3D11TimerQuery.h
  7. 15 3
      Source/BansheeD3D11RenderAPI/Source/BsD3D11EventQuery.cpp
  8. 33 10
      Source/BansheeD3D11RenderAPI/Source/BsD3D11OcclusionQuery.cpp
  9. 34 11
      Source/BansheeD3D11RenderAPI/Source/BsD3D11TimerQuery.cpp
  10. 1 1
      Source/BansheeGLRenderAPI/Include/BsGLEventQuery.h
  11. 2 2
      Source/BansheeGLRenderAPI/Include/BsGLOcclusionQuery.h
  12. 2 2
      Source/BansheeGLRenderAPI/Include/BsGLTimerQuery.h
  13. 15 3
      Source/BansheeGLRenderAPI/Source/BsGLEventQuery.cpp
  14. 32 9
      Source/BansheeGLRenderAPI/Source/BsGLOcclusionQuery.cpp
  15. 31 8
      Source/BansheeGLRenderAPI/Source/BsGLTimerQuery.cpp
  16. 24 2
      Source/BansheeVulkanRenderAPI/Include/BsVulkanEventQuery.h
  17. 3 3
      Source/BansheeVulkanRenderAPI/Include/BsVulkanOcclusionQuery.h
  18. 2 0
      Source/BansheeVulkanRenderAPI/Include/BsVulkanPrerequisites.h
  19. 22 0
      Source/BansheeVulkanRenderAPI/Include/BsVulkanQueryManager.h
  20. 3 0
      Source/BansheeVulkanRenderAPI/Include/BsVulkanRenderAPI.h
  21. 3 3
      Source/BansheeVulkanRenderAPI/Include/BsVulkanTimerQuery.h
  22. 41 5
      Source/BansheeVulkanRenderAPI/Source/BsVulkanEventQuery.cpp
  23. 3 3
      Source/BansheeVulkanRenderAPI/Source/BsVulkanOcclusionQuery.cpp
  24. 54 3
      Source/BansheeVulkanRenderAPI/Source/BsVulkanQueryManager.cpp
  25. 6 1
      Source/BansheeVulkanRenderAPI/Source/BsVulkanRenderAPI.cpp
  26. 3 3
      Source/BansheeVulkanRenderAPI/Source/BsVulkanTimerQuery.cpp

+ 6 - 2
Source/BansheeCore/Include/BsEventQuery.h

@@ -28,12 +28,16 @@ namespace BansheeEngine
 
 		/**
 		 * Starts the query. 
-		 * 			
+		 * 
+		 * @param[in]	cb		Optional command buffer to queue the operation on. If not provided operation
+		 *						is executed on the main command buffer. Otherwise it is executed when 
+		 *						RenderAPI::executeCommands() is called. Buffer must support graphics or compute operations.
+		 * 
 		 * @note	
 		 * Once the query is started you may poll isReady() method to check when query has finished, or you may hook up 
 		 * an #onTriggered callback and be notified that way.
 		 */
-		virtual void begin() = 0;
+		virtual void begin(const SPtr<CommandBuffer>& cb = nullptr) = 0;
 
 		/** Check if GPU has processed the query. */
 		virtual bool isReady() const = 0;

+ 2 - 2
Source/BansheeCore/Include/BsOcclusionQuery.h

@@ -26,14 +26,14 @@ namespace BansheeEngine
 		 *
 		 * @note	Place any commands you want to measure after this call. Call end() when done.
 		 */
-		virtual void begin() = 0;
+		virtual void begin(const SPtr<CommandBuffer>& cb = nullptr) = 0;
 
 		/**
 		 * Stops the query. 
 		 *
 		 * @note	Be aware that queries are executed on the GPU and the results will not be immediately available.
 		 */
-		virtual void end() = 0;
+		virtual void end(const SPtr<CommandBuffer>& cb = nullptr) = 0;
 
 		/** Check if GPU has processed the query. */
 		virtual bool isReady() const = 0;

+ 12 - 4
Source/BansheeCore/Include/BsTimerQuery.h

@@ -23,13 +23,21 @@ namespace BansheeEngine
 
 		/**
 		 * Starts the counter. 
-		 * 			
+		 * 
+		 * @param[in]	cb		Optional command buffer to queue the operation on. If not provided operation
+		 *						is executed on the main command buffer. Otherwise it is executed when 
+		 *						RenderAPI::executeCommands() is called. Buffer must support graphics or compute operations.
+		 *									
 		 * @note	Place any commands you want to measure after this call. Call "end" when done.
 		 */
-		virtual void begin() = 0;
+		virtual void begin(const SPtr<CommandBuffer>& cb = nullptr) = 0;
 
-		/**	Stops the counter. */
-		virtual void end() = 0;
+		/**	
+		 * Stops the counter. 
+		 *
+		 * @param[in]	cb		Command buffer that was provided to the last begin() operation (if any).
+		 */
+		virtual void end(const SPtr<CommandBuffer>& cb = nullptr) = 0;
 
 		/**	Check if GPU has processed the query. */
 		virtual bool isReady() const = 0;

+ 1 - 1
Source/BansheeD3D11RenderAPI/Include/BsD3D11EventQuery.h

@@ -19,7 +19,7 @@ namespace BansheeEngine
 		~D3D11EventQuery();
 
 		/** @copydoc EventQuery::begin */
-		void begin() override;
+		void begin(const SPtr<CommandBuffer>& cb = nullptr) override;
 
 		/** @copydoc EventQuery::isReady */
 		bool isReady() const override;

+ 2 - 2
Source/BansheeD3D11RenderAPI/Include/BsD3D11OcclusionQuery.h

@@ -19,10 +19,10 @@ namespace BansheeEngine
 		~D3D11OcclusionQuery();
 
 		/** @copydoc OcclusionQuery::begin */
-		void begin() override;
+		void begin(const SPtr<CommandBuffer>& cb = nullptr) override;
 
 		/** @copydoc OcclusionQuery::end */
-		void end() override;
+		void end(const SPtr<CommandBuffer>& cb = nullptr) override;
 
 		/** @copydoc OcclusionQuery::isReady */
 		bool isReady() const override;

+ 2 - 2
Source/BansheeD3D11RenderAPI/Include/BsD3D11TimerQuery.h

@@ -19,10 +19,10 @@ namespace BansheeEngine
 		~D3D11TimerQuery();
 
 		/** @copydoc TimerQuery::begin */
-		void begin() override;
+		void begin(const SPtr<CommandBuffer>& cb = nullptr) override;
 
 		/** @copydoc TimerQuery::end */
-		void end() override;
+		void end(const SPtr<CommandBuffer>& cb = nullptr) override;
 
 		/** @copydoc TimerQuery::isReady */
 		bool isReady() const override;

+ 15 - 3
Source/BansheeD3D11RenderAPI/Source/BsD3D11EventQuery.cpp

@@ -3,6 +3,7 @@
 #include "BsD3D11EventQuery.h"
 #include "BsD3D11RenderAPI.h"
 #include "BsD3D11Device.h"
+#include "BsD3D11CommandBuffer.h"
 #include "BsRenderStats.h"
 #include "BsException.h"
 
@@ -41,10 +42,21 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query);
 	}
 
-	void D3D11EventQuery::begin()
+	void D3D11EventQuery::begin(const SPtr<CommandBuffer>& cb)
 	{
-		mContext->End(mQuery);
-		setActive(true);
+		auto execute = [&]()
+		{
+			mContext->End(mQuery);
+			setActive(true);
+		};
+
+		if (cb == nullptr)
+			execute();
+		else
+		{
+			SPtr<D3D11CommandBuffer> d3d11cb = std::static_pointer_cast<D3D11CommandBuffer>(cb);
+			d3d11cb->queueCommand(execute);
+		}
 	}
 
 	bool D3D11EventQuery::isReady() const

+ 33 - 10
Source/BansheeD3D11RenderAPI/Source/BsD3D11OcclusionQuery.cpp

@@ -3,6 +3,7 @@
 #include "BsD3D11OcclusionQuery.h"
 #include "BsD3D11RenderAPI.h"
 #include "BsD3D11Device.h"
+#include "BsD3D11CommandBuffer.h"
 #include "BsRenderStats.h"
 #include "BsMath.h"
 
@@ -37,22 +38,44 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query);
 	}
 
-	void D3D11OcclusionQuery::begin()
+	void D3D11OcclusionQuery::begin(const SPtr<CommandBuffer>& cb)
 	{
-		mContext->Begin(mQuery);
+		auto execute = [&]()
+		{
+			mContext->Begin(mQuery);
+
+			mNumSamples = 0;
+			mQueryEndCalled = false;
+
+			setActive(true);
+		};
 
-		mNumSamples = 0;
-		mQueryEndCalled = false;
-		
-		setActive(true);
+		if (cb == nullptr)
+			execute();
+		else
+		{
+			SPtr<D3D11CommandBuffer> d3d11CB = std::static_pointer_cast<D3D11CommandBuffer>(cb);
+			d3d11CB->queueCommand(execute);
+		}
 	}
 
-	void D3D11OcclusionQuery::end()
+	void D3D11OcclusionQuery::end(const SPtr<CommandBuffer>& cb)
 	{
-		mContext->End(mQuery);
+		auto execute = [&]()
+		{
+			mContext->End(mQuery);
+
+			mQueryEndCalled = true;
+			mFinalized = false;
+		};
 
-		mQueryEndCalled = true;
-		mFinalized = false;
+		if (cb == nullptr)
+			execute();
+		else
+		{
+			SPtr<D3D11CommandBuffer> d3d11CB = std::static_pointer_cast<D3D11CommandBuffer>(cb);
+			d3d11CB->queueCommand(execute);
+		}
 	}
 
 	bool D3D11OcclusionQuery::isReady() const

+ 34 - 11
Source/BansheeD3D11RenderAPI/Source/BsD3D11TimerQuery.cpp

@@ -3,6 +3,7 @@
 #include "BsD3D11TimerQuery.h"
 #include "BsD3D11RenderAPI.h"
 #include "BsD3D11Device.h"
+#include "BsD3D11CommandBuffer.h"
 #include "BsRenderStats.h"
 #include "BsDebug.h"
 
@@ -59,23 +60,45 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query);
 	}
 
-	void D3D11TimerQuery::begin()
+	void D3D11TimerQuery::begin(const SPtr<CommandBuffer>& cb)
 	{
-		mContext->Begin(mDisjointQuery);
-		mContext->End(mBeginQuery);
+		auto execute = [&]()
+		{
+			mContext->Begin(mDisjointQuery);
+			mContext->End(mBeginQuery);
+
+			mQueryEndCalled = false;
+
+			setActive(true);
+		};
 
-		mQueryEndCalled = false;
-		
-		setActive(true);
+		if (cb == nullptr)
+			execute();
+		else
+		{
+			SPtr<D3D11CommandBuffer> d3d11cb = std::static_pointer_cast<D3D11CommandBuffer>(cb);
+			d3d11cb->queueCommand(execute);
+		}
 	}
 
-	void D3D11TimerQuery::end()
+	void D3D11TimerQuery::end(const SPtr<CommandBuffer>& cb)
 	{
-		mContext->End(mEndQuery);
-		mContext->End(mDisjointQuery);
+		auto execute = [&]()
+		{
+			mContext->End(mEndQuery);
+			mContext->End(mDisjointQuery);
+
+			mQueryEndCalled = true;
+			mFinalized = false;
+		};
 
-		mQueryEndCalled = true;
-		mFinalized = false;
+		if (cb == nullptr)
+			execute();
+		else
+		{
+			SPtr<D3D11CommandBuffer> d3d11cb = std::static_pointer_cast<D3D11CommandBuffer>(cb);
+			d3d11cb->queueCommand(execute);
+		}
 	}
 
 	bool D3D11TimerQuery::isReady() const

+ 1 - 1
Source/BansheeGLRenderAPI/Include/BsGLEventQuery.h

@@ -19,7 +19,7 @@ namespace BansheeEngine
 		~GLEventQuery();
 
 		/** @copydoc EventQuery::begin */
-		void begin() override;
+		void begin(const SPtr<CommandBuffer>& cb = nullptr) override;
 
 		/** @copydoc EventQuery::isReady */
 		bool isReady() const override;

+ 2 - 2
Source/BansheeGLRenderAPI/Include/BsGLOcclusionQuery.h

@@ -19,10 +19,10 @@ namespace BansheeEngine
 		~GLOcclusionQuery();
 
 		/** @copydoc OcclusionQuery::begin */
-		void begin() override;
+		void begin(const SPtr<CommandBuffer>& cb = nullptr) override;
 
 		/** @copydoc OcclusionQuery::end */
-		void end() override;
+		void end(const SPtr<CommandBuffer>& cb = nullptr) override;
 
 		/** @copydoc OcclusionQuery::isReady */
 		bool isReady() const override;

+ 2 - 2
Source/BansheeGLRenderAPI/Include/BsGLTimerQuery.h

@@ -19,10 +19,10 @@ namespace BansheeEngine
 		~GLTimerQuery();
 
 		/** @copydoc TimerQuery::begin */
-		void begin() override;
+		void begin(const SPtr<CommandBuffer>& cb = nullptr) override;
 
 		/** @copydoc TimerQuery::end */
-		void end() override;
+		void end(const SPtr<CommandBuffer>& cb = nullptr) override;
 
 		/** @copydoc TimerQuery::isReady */
 		bool isReady() const override;

+ 15 - 3
Source/BansheeGLRenderAPI/Source/BsGLEventQuery.cpp

@@ -1,6 +1,7 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 #include "BsGLEventQuery.h"
+#include "BsGLCommandBuffer.h"
 #include "BsRenderStats.h"
 
 namespace BansheeEngine
@@ -20,10 +21,21 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query);
 	}
 
-	void GLEventQuery::begin()
+	void GLEventQuery::begin(const SPtr<CommandBuffer>& cb)
 	{
-		glQueryCounter(mQueryObj, GL_TIMESTAMP);
-		setActive(true);
+		auto execute = [&]()
+		{
+			glQueryCounter(mQueryObj, GL_TIMESTAMP);
+			setActive(true);
+		};
+
+		if (cb == nullptr)
+			execute();
+		else
+		{
+			SPtr<GLCommandBuffer> glCB = std::static_pointer_cast<GLCommandBuffer>(cb);
+			glCB->queueCommand(execute);
+		}
 	}
 
 	bool GLEventQuery::isReady() const

+ 32 - 9
Source/BansheeGLRenderAPI/Source/BsGLOcclusionQuery.cpp

@@ -1,6 +1,7 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 #include "BsGLOcclusionQuery.h"
+#include "BsGLCommandBuffer.h"
 #include "BsMath.h"
 #include "BsRenderStats.h"
 
@@ -21,21 +22,43 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query);
 	}
 
-	void GLOcclusionQuery::begin()
+	void GLOcclusionQuery::begin(const SPtr<CommandBuffer>& cb)
 	{
-		glBeginQuery(mBinary ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED, mQueryObj);
+		auto execute = [&]()
+		{
+			glBeginQuery(mBinary ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED, mQueryObj);
+
+			mNumSamples = 0;
+			mEndIssued = false;
+			setActive(true);
+		};
 
-		mNumSamples = 0;
-		mEndIssued = false;
-		setActive(true);
+		if (cb == nullptr)
+			execute();
+		else
+		{
+			SPtr<GLCommandBuffer> glCB = std::static_pointer_cast<GLCommandBuffer>(cb);
+			glCB->queueCommand(execute);
+		}
 	}
 
-	void GLOcclusionQuery::end()
+	void GLOcclusionQuery::end(const SPtr<CommandBuffer>& cb)
 	{
-		glEndQuery(mBinary ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED);
+		auto execute = [&]()
+		{
+			glEndQuery(mBinary ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED);
+
+			mEndIssued = true;
+			mFinalized = false;
+		};
 
-		mEndIssued = true;
-		mFinalized = false;
+		if (cb == nullptr)
+			execute();
+		else
+		{
+			SPtr<GLCommandBuffer> glCB = std::static_pointer_cast<GLCommandBuffer>(cb);
+			glCB->queueCommand(execute);
+		}
 	}
 
 	bool GLOcclusionQuery::isReady() const

+ 31 - 8
Source/BansheeGLRenderAPI/Source/BsGLTimerQuery.cpp

@@ -1,6 +1,7 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 #include "BsGLTimerQuery.h"
+#include "BsGLCommandBuffer.h"
 #include "BsMath.h"
 #include "BsRenderStats.h"
 
@@ -31,20 +32,42 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query);
 	}
 
-	void GLTimerQuery::begin()
+	void GLTimerQuery::begin(const SPtr<CommandBuffer>& cb)
 	{
-		glQueryCounter(mQueryStartObj, GL_TIMESTAMP);
+		auto execute = [&]()
+		{
+			glQueryCounter(mQueryStartObj, GL_TIMESTAMP);
+
+			setActive(true);
+			mEndIssued = false;
+		};
 
-		setActive(true);
-		mEndIssued = false;
+		if (cb == nullptr)
+			execute();
+		else
+		{
+			SPtr<GLCommandBuffer> glCB = std::static_pointer_cast<GLCommandBuffer>(cb);
+			glCB->queueCommand(execute);
+		}
 	}
 
-	void GLTimerQuery::end()
+	void GLTimerQuery::end(const SPtr<CommandBuffer>& cb)
 	{
-		glQueryCounter(mQueryEndObj, GL_TIMESTAMP);
+		auto execute = [&]()
+		{
+			glQueryCounter(mQueryEndObj, GL_TIMESTAMP);
+
+			mEndIssued = true;
+			mFinalized = false;
+		};
 
-		mEndIssued = true;
-		mFinalized = false;
+		if (cb == nullptr)
+			execute();
+		else
+		{
+			SPtr<GLCommandBuffer> glCB = std::static_pointer_cast<GLCommandBuffer>(cb);
+			glCB->queueCommand(execute);
+		}
 	}
 
 	bool GLTimerQuery::isReady() const

+ 24 - 2
Source/BansheeVulkanRenderAPI/Include/BsVulkanEventQuery.h

@@ -3,6 +3,7 @@
 #pragma once
 
 #include "BsVulkanPrerequisites.h"
+#include "BsVulkanResource.h"
 #include "BsEventQuery.h"
 
 namespace BansheeEngine
@@ -11,20 +12,41 @@ namespace BansheeEngine
 	 *  @{
 	 */
 
+	/** Wrapper around a Vulkan event object that manages its usage and lifetime. */
+	class VulkanEvent : public VulkanResource
+	{
+	public:
+		VulkanEvent(VulkanResourceManager* owner);
+		~VulkanEvent();
+
+		/** Returns the internal handle to the Vulkan object. */
+		VkEvent getHandle() const { return mEvent; }
+
+		/** Checks if the event has been signaled on the device. */
+		bool isSignaled() const;
+
+		/** Resets an event back to unsignaled state, making it re-usable. */
+		void reset();
+	private:
+		VkEvent mEvent;
+	};
+
 	/** @copydoc EventQuery */
 	class VulkanEventQuery : public EventQuery
 	{
 	public:
-		VulkanEventQuery(UINT32 deviceIdx);
+		VulkanEventQuery(VulkanDevice& device);
 		~VulkanEventQuery();
 
 		/** @copydoc EventQuery::begin */
-		void begin() override;
+		void begin(const SPtr<CommandBuffer>& cb = nullptr) override;
 
 		/** @copydoc EventQuery::isReady */
 		bool isReady() const override;
 
 	private:
+		VulkanDevice& mDevice;
+		VulkanEvent* mEvent;
 	};
 
 	/** @} */

+ 3 - 3
Source/BansheeVulkanRenderAPI/Include/BsVulkanOcclusionQuery.h

@@ -15,14 +15,14 @@ namespace BansheeEngine
 	class VulkanOcclusionQuery : public OcclusionQuery
 	{
 	public:
-		VulkanOcclusionQuery(bool binary, UINT32 deviceIdx);
+		VulkanOcclusionQuery(VulkanDevice& device, bool binary);
 		~VulkanOcclusionQuery();
 
 		/** @copydoc OcclusionQuery::begin */
-		void begin() override;
+		void begin(const SPtr<CommandBuffer>& cb = nullptr) override;
 
 		/** @copydoc OcclusionQuery::end */
-		void end() override;
+		void end(const SPtr<CommandBuffer>& cb = nullptr) override;
 
 		/** @copydoc OcclusionQuery::isReady */
 		bool isReady() const override;

+ 2 - 0
Source/BansheeVulkanRenderAPI/Include/BsVulkanPrerequisites.h

@@ -57,6 +57,8 @@ namespace BansheeEngine
 	class VulkanDescriptorPool;
 	class VulkanGpuParams;
 	class VulkanTransferBuffer;
+	class VulkanEvent;
+	class VulkanQuery;
 
 	VkAllocationCallbacks* gVulkanAllocator = nullptr;
 

+ 22 - 0
Source/BansheeVulkanRenderAPI/Include/BsVulkanQueryManager.h

@@ -3,6 +3,7 @@
 #pragma once
 
 #include "BsVulkanPrerequisites.h"
+#include "BsVulkanResource.h"
 #include "BsQueryManager.h"
 
 namespace BansheeEngine
@@ -15,6 +16,9 @@ namespace BansheeEngine
 	class VulkanQueryManager : public QueryManager
 	{
 	public:
+		VulkanQueryManager(VulkanRenderAPI& rapi);
+		~VulkanQueryManager();
+
 		/** @copydoc QueryManager::createEventQuery */
 		SPtr<EventQuery> createEventQuery(UINT32 deviceIdx = 0) const override;
 
@@ -23,7 +27,25 @@ namespace BansheeEngine
 
 		/** @copydoc QueryManager::createOcclusionQuery */
 		SPtr<OcclusionQuery> createOcclusionQuery(bool binary, UINT32 deviceIdx = 0) const override;
+
+	private:
+		VulkanRenderAPI& mRenderAPI;
 	};
 
+	/** Wrapper around a single query in a Vulkan query pool object. */
+	class VulkanQuery : public VulkanResource
+	{
+	public:
+		VulkanQuery(VulkanResourceManager* owner);
+		~VulkanQuery();
+
+		/** Returns the internal handle to the Vulkan object. */
+		bool setUsed(bool used) const { return mEvent; }
+
+	private:
+		VkEvent mEvent;
+	};
+
+
 	/** @} */
 }

+ 3 - 0
Source/BansheeVulkanRenderAPI/Include/BsVulkanRenderAPI.h

@@ -169,6 +169,9 @@ namespace BansheeEngine
 #endif
 	};
 
+	/**	Provides easy access to the VulkanRenderAPI. */
+	VulkanRenderAPI& gVulkanRenderAPI();
+
 	extern PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
 	extern PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
 	extern PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;

+ 3 - 3
Source/BansheeVulkanRenderAPI/Include/BsVulkanTimerQuery.h

@@ -15,14 +15,14 @@ namespace BansheeEngine
 	class VulkanTimerQuery : public TimerQuery
 	{
 	public:
-		VulkanTimerQuery(UINT32 deviceIdx);
+		VulkanTimerQuery(VulkanDevice& device);
 		~VulkanTimerQuery();
 
 		/** @copydoc TimerQuery::begin */
-		void begin() override;
+		void begin(const SPtr<CommandBuffer>& cb = nullptr) override;
 
 		/** @copydoc TimerQuery::end */
-		void end() override;
+		void end(const SPtr<CommandBuffer>& cb = nullptr) override;
 
 		/** @copydoc TimerQuery::isReady */
 		bool isReady() const override;

+ 41 - 5
Source/BansheeVulkanRenderAPI/Source/BsVulkanEventQuery.cpp

@@ -1,29 +1,65 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 #include "BsVulkanEventQuery.h"
-#include "BsVulkanRenderAPI.h"
+#include "BsVulkanDevice.h"
+#include "BsVulkanCommandBuffer.h"
 #include "BsRenderStats.h"
-#include "BsException.h"
 
 namespace BansheeEngine
 {
-	VulkanEventQuery::VulkanEventQuery(UINT32 deviceIdx)
+	VulkanEventQuery::VulkanEventQuery(VulkanDevice& device)
+		:mDevice(device), mEvent(nullptr)
 	{
 		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_Query);
 	}
 
 	VulkanEventQuery::~VulkanEventQuery()
 	{
+		if (mEvent != nullptr)
+			mEvent->destroy();
+
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query);
 	}
 
-	void VulkanEventQuery::begin()
+	void VulkanEventQuery::begin(const SPtr<CommandBuffer>& cb)
 	{
+		if (mEvent != nullptr)
+		{
+			if (mEvent->isBound())
+			{
+				// Clear current event and create a new one
+				mEvent->destroy();
+				mEvent = mDevice.getResourceManager().create<VulkanEvent>();
+			}
+			else
+			{
+				// Re-use existing event
+				mEvent->reset();
+			}
+		}
+		else // Create new event
+			mEvent = mDevice.getResourceManager().create<VulkanEvent>();
+
+		VulkanCommandBuffer* vulkanCB;
+		if (cb != nullptr)
+			vulkanCB = static_cast<VulkanCommandBuffer*>(cb.get());
+		else
+			vulkanCB = static_cast<VulkanCommandBuffer*>(gVulkanRenderAPI()._getMainCommandBuffer());
+
+		VulkanCmdBuffer* internalCB = vulkanCB->getInternal(); 
+		internalCB->registerResource(mEvent, VulkanUseFlag::Read);
+
+		VkCommandBuffer vkCB = internalCB->getHandle();
+		vkCmdSetEvent(vkCB, mEvent->getHandle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
+
 		setActive(true);
 	}
 
 	bool VulkanEventQuery::isReady() const
 	{
-		return false;
+		if (mEvent == nullptr)
+			return false;
+
+		return mEvent->isSignaled();
 	}
 }

+ 3 - 3
Source/BansheeVulkanRenderAPI/Source/BsVulkanOcclusionQuery.cpp

@@ -5,7 +5,7 @@
 
 namespace BansheeEngine
 {
-	VulkanOcclusionQuery::VulkanOcclusionQuery(bool binary, UINT32 deviceIdx)
+	VulkanOcclusionQuery::VulkanOcclusionQuery(VulkanDevice& device, bool binary)
 		:OcclusionQuery(binary)
 	{
 		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_Query);
@@ -16,12 +16,12 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query);
 	}
 
-	void VulkanOcclusionQuery::begin()
+	void VulkanOcclusionQuery::begin(const SPtr<CommandBuffer>& cb)
 	{
 		setActive(true);
 	}
 
-	void VulkanOcclusionQuery::end()
+	void VulkanOcclusionQuery::end(const SPtr<CommandBuffer>& cb)
 	{
 
 	}

+ 54 - 3
Source/BansheeVulkanRenderAPI/Source/BsVulkanQueryManager.cpp

@@ -4,12 +4,25 @@
 #include "BsVulkanEventQuery.h"
 #include "BsVulkanTimerQuery.h"
 #include "BsVulkanOcclusionQuery.h"
+#include "BsVulkanRenderAPI.h"
+#include "BsVulkanDevice.h"
 
 namespace BansheeEngine
 {
+	VulkanQueryManager::VulkanQueryManager(VulkanRenderAPI& rapi)
+		:mRenderAPI(rapi)
+	{ }
+
+	VulkanQueryManager::~VulkanQueryManager()
+	{
+		
+	}
+
 	SPtr<EventQuery> VulkanQueryManager::createEventQuery(UINT32 deviceIdx) const
 	{
-		SPtr<EventQuery> query = SPtr<VulkanEventQuery>(bs_new<VulkanEventQuery>(deviceIdx), 
+		SPtr<VulkanDevice> device = mRenderAPI._getDevice(deviceIdx);
+
+		SPtr<EventQuery> query = SPtr<VulkanEventQuery>(bs_new<VulkanEventQuery>(*device),
 			&QueryManager::deleteEventQuery, StdAlloc<VulkanEventQuery>());
 		mEventQueries.push_back(query.get());
 
@@ -18,7 +31,9 @@ namespace BansheeEngine
 
 	SPtr<TimerQuery> VulkanQueryManager::createTimerQuery(UINT32 deviceIdx) const
 	{
-		SPtr<TimerQuery> query = SPtr<VulkanTimerQuery>(bs_new<VulkanTimerQuery>(deviceIdx), 
+		SPtr<VulkanDevice> device = mRenderAPI._getDevice(deviceIdx);
+
+		SPtr<TimerQuery> query = SPtr<VulkanTimerQuery>(bs_new<VulkanTimerQuery>(device),
 			&QueryManager::deleteTimerQuery, StdAlloc<VulkanTimerQuery>());
 		mTimerQueries.push_back(query.get());
 
@@ -27,10 +42,46 @@ namespace BansheeEngine
 
 	SPtr<OcclusionQuery> VulkanQueryManager::createOcclusionQuery(bool binary, UINT32 deviceIdx) const
 	{
-		SPtr<OcclusionQuery> query = SPtr<VulkanOcclusionQuery>(bs_new<VulkanOcclusionQuery>(binary, deviceIdx),
+		SPtr<VulkanDevice> device = mRenderAPI._getDevice(deviceIdx);
+
+		SPtr<OcclusionQuery> query = SPtr<VulkanOcclusionQuery>(bs_new<VulkanOcclusionQuery>(*device, binary),
 			&QueryManager::deleteOcclusionQuery, StdAlloc<VulkanOcclusionQuery>());
 		mOcclusionQueries.push_back(query.get());
 
 		return query;
 	}
+
+	VulkanEvent::VulkanEvent(VulkanResourceManager* owner)
+		:VulkanResource(owner, false)
+	{
+		VkDevice vkDevice = owner->getDevice().getLogical();
+
+		VkEventCreateInfo eventCI;
+		eventCI.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
+		eventCI.pNext = nullptr;
+		eventCI.flags = 0;
+
+		VkResult result = vkCreateEvent(vkDevice, &eventCI, gVulkanAllocator, &mEvent);
+		assert(result == VK_SUCCESS);
+	}
+
+	VulkanEvent::~VulkanEvent()
+	{
+		VkDevice vkDevice = mOwner->getDevice().getLogical();
+		vkDestroyEvent(vkDevice, mEvent, gVulkanAllocator);
+	}
+
+	bool VulkanEvent::isSignaled() const
+	{
+		VkDevice vkDevice = mOwner->getDevice().getLogical();
+		return vkGetEventStatus(vkDevice, mEvent) == VK_EVENT_SET;
+	}
+
+	void VulkanEvent::reset()
+	{
+		VkDevice vkDevice = mOwner->getDevice().getLogical();
+
+		VkResult result = vkResetEvent(vkDevice, mEvent);
+		assert(result == VK_SUCCESS);
+	}
 }

+ 6 - 1
Source/BansheeVulkanRenderAPI/Source/BsVulkanRenderAPI.cpp

@@ -242,7 +242,7 @@ namespace BansheeEngine
 		RenderWindowCoreManager::startUp<VulkanRenderWindowCoreManager>(*this);
 
 		// Create query manager 
-		QueryManager::startUp<VulkanQueryManager>();
+		QueryManager::startUp<VulkanQueryManager>(*this);
 
 		// Create vertex input manager
 		VulkanVertexInputManager::startUp();
@@ -698,4 +698,9 @@ namespace BansheeEngine
 
 		return static_cast<VulkanCommandBuffer*>(mMainCommandBuffer.get());
 	}
+
+	VulkanRenderAPI& gVulkanRenderAPI()
+	{
+		return static_cast<VulkanRenderAPI&>(RenderAPICore::instance());
+	}
 }

+ 3 - 3
Source/BansheeVulkanRenderAPI/Source/BsVulkanTimerQuery.cpp

@@ -5,7 +5,7 @@
 
 namespace BansheeEngine
 {
-	VulkanTimerQuery::VulkanTimerQuery(UINT32 deviceIdx)
+	VulkanTimerQuery::VulkanTimerQuery(VulkanDevice& device)
 	{
 		BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_Query);
 	}
@@ -15,12 +15,12 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Query);
 	}
 
-	void VulkanTimerQuery::begin()
+	void VulkanTimerQuery::begin(const SPtr<CommandBuffer>& cb)
 	{
 		setActive(true);
 	}
 
-	void VulkanTimerQuery::end()
+	void VulkanTimerQuery::end(const SPtr<CommandBuffer>& cb)
 	{
 
 	}