소스 검색

Fixing command buffer synchronization logic: Command buffers with different IDs now properly ignore sync if they are executing on the same queue

BearishSun 9 년 전
부모
커밋
1d6bc6a027
24개의 변경된 파일133개의 추가작업 그리고 115개의 파일을 삭제
  1. 12 3
      Source/BansheeCore/Include/BsCommandBuffer.h
  2. 2 2
      Source/BansheeCore/Include/BsCommandBufferManager.h
  3. 11 10
      Source/BansheeCore/Include/BsCommonTypes.h
  4. 23 3
      Source/BansheeCore/Source/BsCommandBuffer.cpp
  5. 1 1
      Source/BansheeCore/Source/BsCommandBufferManager.cpp
  6. 1 1
      Source/BansheeD3D11RenderAPI/Include/BsD3D11CommandBuffer.h
  7. 1 1
      Source/BansheeD3D11RenderAPI/Include/BsD3D11CommandBufferManager.h
  8. 1 1
      Source/BansheeD3D11RenderAPI/Source/BsD3D11CommandBuffer.cpp
  9. 1 1
      Source/BansheeD3D11RenderAPI/Source/BsD3D11CommandBufferManager.cpp
  10. 3 0
      Source/BansheeEngine/Include/BsBuiltinResourcesHelper.h
  11. 1 1
      Source/BansheeGLRenderAPI/Include/BsGLCommandBuffer.h
  12. 1 1
      Source/BansheeGLRenderAPI/Include/BsGLCommandBufferManager.h
  13. 1 1
      Source/BansheeGLRenderAPI/Source/BsGLCommandBuffer.cpp
  14. 1 1
      Source/BansheeGLRenderAPI/Source/BsGLCommandBufferManager.cpp
  15. 16 7
      Source/BansheeVulkanRenderAPI/Include/BsVulkanCommandBuffer.h
  16. 1 1
      Source/BansheeVulkanRenderAPI/Include/BsVulkanCommandBufferManager.h
  17. 4 4
      Source/BansheeVulkanRenderAPI/Include/BsVulkanDevice.h
  18. 0 15
      Source/BansheeVulkanRenderAPI/Include/BsVulkanPrerequisites.h
  19. 0 3
      Source/BansheeVulkanRenderAPI/Include/BsVulkanUtility.h
  20. 38 30
      Source/BansheeVulkanRenderAPI/Source/BsVulkanCommandBuffer.cpp
  21. 6 4
      Source/BansheeVulkanRenderAPI/Source/BsVulkanCommandBufferManager.cpp
  22. 7 7
      Source/BansheeVulkanRenderAPI/Source/BsVulkanDevice.cpp
  23. 0 16
      Source/BansheeVulkanRenderAPI/Source/BsVulkanUtility.cpp
  24. 1 1
      Source/BansheeVulkanRenderAPI/Source/Win32/BsWin32RenderWindow.cpp

+ 12 - 3
Source/BansheeCore/Include/BsCommandBuffer.h

@@ -23,6 +23,9 @@ namespace BansheeEngine
 		/** Returns a combined mask that contains all the required dependencies. */
 		UINT32 getMask() const { return mMask; }
 
+		/** Uses the queue type and index to generate a global queue index. */
+		static UINT32 getGlobalQueueIdx(GpuQueueType type, UINT32 queueIdx);
+
 	private:
 		UINT32 mMask = 0;
 	};
@@ -56,9 +59,15 @@ namespace BansheeEngine
 		 * @note The parallelism provided by @p queueIdx is parallelism on the GPU itself, it has nothing to do with CPU
 		 *		 parallelism or threads.
 		 */
-		static SPtr<CommandBuffer> create(CommandBufferType type, UINT32 deviceIdx = 0, UINT32 queueIdx = 0, 
+		static SPtr<CommandBuffer> create(GpuQueueType type, UINT32 deviceIdx = 0, UINT32 queueIdx = 0,
 			bool secondary = false);
 
+		/** Returns the type of queue the command buffer will execute on. */
+		GpuQueueType getType() const { return mType; }
+
+		/** Returns the index of the queue the command buffer will execute on. */
+		UINT32 getQueueIdx() const { return mQueueIdx; }
+
 		/** @name Internal
 		 *  @{
 		 */
@@ -68,10 +77,10 @@ namespace BansheeEngine
 
 		/** @} */
 	protected:
-		CommandBuffer(UINT32 id, CommandBufferType type, UINT32 deviceIdx, UINT32 queueIdx, bool secondary);
+		CommandBuffer(UINT32 id, GpuQueueType type, UINT32 deviceIdx, UINT32 queueIdx, bool secondary);
 
 		UINT32 mId;
-		CommandBufferType mType;
+		GpuQueueType mType;
 		UINT32 mDeviceIdx;
 		UINT32 mQueueIdx;
 		bool mIsSecondary;

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

@@ -22,14 +22,14 @@ namespace BansheeEngine
 		virtual ~CommandBufferManager() {}
 
 		/** @copydoc CommandBuffer::create */
-		SPtr<CommandBuffer> create(CommandBufferType type, UINT32 deviceIdx = 0, UINT32 queueIdx = 0,
+		SPtr<CommandBuffer> create(GpuQueueType type, UINT32 deviceIdx = 0, UINT32 queueIdx = 0,
 			bool secondary = false);
 
 	protected:
 		friend CommandBuffer;
 
 		/** Creates a command buffer with the specified ID. See create(). */
-		virtual SPtr<CommandBuffer> createInternal(UINT32 id, CommandBufferType type, UINT32 deviceIdx = 0, 
+		virtual SPtr<CommandBuffer> createInternal(UINT32 id, GpuQueueType type, UINT32 deviceIdx = 0,
 			UINT32 queueIdx = 0, bool secondary = false) = 0;
 
 		/** Called by a command buffer just before it is destroyed. */

+ 11 - 10
Source/BansheeCore/Include/BsCommonTypes.h

@@ -391,18 +391,19 @@ namespace BansheeEngine
 		GPOT_UNKNOWN = 0xffff
 	};
 
-	/** Types of command buffers. */
-	enum CommandBufferType
+	/** Types of GPU queues. */
+	enum GpuQueueType
 	{
-		/** 
-		 * Command buffer used for rendering. Allows the use of draw commands, but also all commands supported by compute
-		 * or upload buffers. 
+		/**
+		 * Queue used for rendering. Allows the use of draw commands, but also all commands supported by compute
+		 * or upload buffers.
 		 */
-		CBT_GRAPHICS,
-		/** Command buffer used for compute operations. Allows the use of dispatch and upload commands. */
-		CBT_COMPUTE,
-		/** Command buffer used for memory transfer operations only. No rendering or compute dispatch allowed. */
-		CBT_UPLOAD
+		GQT_GRAPHICS,
+		/** Discrete queue used for compute operations. Allows the use of dispatch and upload commands. */
+		GQT_COMPUTE,
+		/** Queue used for memory transfer operations only. No rendering or compute dispatch allowed. */
+		GQT_UPLOAD,
+		GQT_COUNT // Keep at end
 	};
 
 	/** These values represent a hint to the driver when writing to a GPU buffer. */

+ 23 - 3
Source/BansheeCore/Source/BsCommandBuffer.cpp

@@ -10,10 +10,30 @@ namespace BansheeEngine
 		if (buffer == nullptr)
 			return;
 
-		mMask |= 1 << buffer->_getId();
+		mMask |= getGlobalQueueIdx(buffer->getType(), buffer->getQueueIdx());
 	}
 
-	CommandBuffer::CommandBuffer(UINT32 id, CommandBufferType type, UINT32 deviceIdx, UINT32 queueIdx, bool secondary)
+	UINT32 CommandSyncMask::getGlobalQueueIdx(GpuQueueType type, UINT32 queueIdx)
+	{
+		UINT32 bitShift = 0;
+		switch (type)
+		{
+		case GQT_GRAPHICS:
+			break;
+		case GQT_COMPUTE:
+			bitShift = 8;
+			break;
+		case GQT_UPLOAD:
+			bitShift = 16;
+			break;
+		default:
+			break;
+		}
+
+		return (1 << queueIdx) << bitShift;
+	}
+
+	CommandBuffer::CommandBuffer(UINT32 id, GpuQueueType type, UINT32 deviceIdx, UINT32 queueIdx, bool secondary)
 		:mId(id), mType(type), mDeviceIdx(deviceIdx), mQueueIdx(queueIdx), mIsSecondary(secondary)
 	{
 
@@ -24,7 +44,7 @@ namespace BansheeEngine
 		CommandBufferManager::instance().notifyCommandBufferDestroyed(mDeviceIdx, mId);
 	}
 
-	SPtr<CommandBuffer> CommandBuffer::create(CommandBufferType type, UINT32 deviceIdx, UINT32 queueIdx,
+	SPtr<CommandBuffer> CommandBuffer::create(GpuQueueType type, UINT32 deviceIdx, UINT32 queueIdx,
 		bool secondary)
 	{
 		return CommandBufferManager::instance().create(type, deviceIdx, queueIdx, secondary);

+ 1 - 1
Source/BansheeCore/Source/BsCommandBufferManager.cpp

@@ -4,7 +4,7 @@
 
 namespace BansheeEngine
 {
-	SPtr<CommandBuffer> CommandBufferManager::create(CommandBufferType type, UINT32 deviceIdx, UINT32 queueIdx,
+	SPtr<CommandBuffer> CommandBufferManager::create(GpuQueueType type, UINT32 deviceIdx, UINT32 queueIdx,
 		bool secondary)
 	{
 		assert(deviceIdx < BS_MAX_DEVICES);

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

@@ -35,7 +35,7 @@ namespace BansheeEngine
 		friend class D3D11CommandBufferManager;
 		friend class D3D11RenderAPI;
 
-		D3D11CommandBuffer(UINT32 id, CommandBufferType type, UINT32 deviceIdx, UINT32 queueIdx, bool secondary);
+		D3D11CommandBuffer(UINT32 id, GpuQueueType type, UINT32 deviceIdx, UINT32 queueIdx, bool secondary);
 
 		Vector<std::function<void()>> mCommands;
 

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

@@ -20,7 +20,7 @@ namespace BansheeEngine
 	{
 	public:
 		/** @copydoc CommandBufferManager::createInternal() */
-		SPtr<CommandBuffer> createInternal(UINT32 id, CommandBufferType type, UINT32 deviceIdx = 0, UINT32 queueIdx = 0, 
+		SPtr<CommandBuffer> createInternal(UINT32 id, GpuQueueType type, UINT32 deviceIdx = 0, UINT32 queueIdx = 0,
 			bool secondary = false) override;
 	};
 

+ 1 - 1
Source/BansheeD3D11RenderAPI/Source/BsD3D11CommandBuffer.cpp

@@ -4,7 +4,7 @@
 
 namespace BansheeEngine
 {
-	D3D11CommandBuffer::D3D11CommandBuffer(UINT32 id, CommandBufferType type, UINT32 deviceIdx, UINT32 queueIdx, bool secondary)
+	D3D11CommandBuffer::D3D11CommandBuffer(UINT32 id, GpuQueueType type, UINT32 deviceIdx, UINT32 queueIdx, bool secondary)
 		: CommandBuffer(id, type, deviceIdx, queueIdx, secondary), mActiveDrawOp(DOT_TRIANGLE_LIST)
 	{
 		if (deviceIdx != 0)

+ 1 - 1
Source/BansheeD3D11RenderAPI/Source/BsD3D11CommandBufferManager.cpp

@@ -5,7 +5,7 @@
 
 namespace BansheeEngine
 {
-	SPtr<CommandBuffer> D3D11CommandBufferManager::createInternal(UINT32 id, CommandBufferType type, UINT32 deviceIdx, 
+	SPtr<CommandBuffer> D3D11CommandBufferManager::createInternal(UINT32 id, GpuQueueType type, UINT32 deviceIdx,
 		UINT32 queueIdx, bool secondary)
 	{
 		CommandBuffer* buffer = new (bs_alloc<D3D11CommandBuffer>()) D3D11CommandBuffer(id, type, deviceIdx, queueIdx, secondary);

+ 3 - 0
Source/BansheeEngine/Include/BsBuiltinResourcesHelper.h

@@ -11,6 +11,9 @@ namespace BansheeEngine
 	 *  @{
 	 */
 
+	//using Json = nlohmann::basic_json<Map, Vector, String, bool, INT64, UINT64, float, StdAlloc>;
+	//using WJson = nlohmann::basic_json<Map, Vector, WString, bool, INT64, UINT64, float, StdAlloc>;
+
 	/**	Provides various methods commonly used for managing builtin resources. */
 	class BS_EXPORT BuiltinResourcesHelper
 	{

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

@@ -35,7 +35,7 @@ namespace BansheeEngine
 		friend class GLCommandBufferManager;
 		friend class GLRenderAPI;
 
-		GLCommandBuffer(UINT32 id, CommandBufferType type, UINT32 deviceIdx, UINT32 queueIdx, bool secondary);
+		GLCommandBuffer(UINT32 id, GpuQueueType type, UINT32 deviceIdx, UINT32 queueIdx, bool secondary);
 
 		Vector<std::function<void()>> mCommands;
 

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

@@ -20,7 +20,7 @@ namespace BansheeEngine
 	{
 	public:
 		/** @copydoc CommandBufferManager::createInternal() */
-		SPtr<CommandBuffer> createInternal(UINT32 id, CommandBufferType type, UINT32 deviceIdx = 0, UINT32 queueIdx = 0, 
+		SPtr<CommandBuffer> createInternal(UINT32 id, GpuQueueType type, UINT32 deviceIdx = 0, UINT32 queueIdx = 0,
 			bool secondary = false) override;
 	};
 

+ 1 - 1
Source/BansheeGLRenderAPI/Source/BsGLCommandBuffer.cpp

@@ -4,7 +4,7 @@
 
 namespace BansheeEngine
 {
-	GLCommandBuffer::GLCommandBuffer(UINT32 id, CommandBufferType type, UINT32 deviceIdx, UINT32 queueIdx, bool secondary)
+	GLCommandBuffer::GLCommandBuffer(UINT32 id, GpuQueueType type, UINT32 deviceIdx, UINT32 queueIdx, bool secondary)
 		: CommandBuffer(id, type, deviceIdx, queueIdx, secondary), mCurrentDrawOperation(DOT_TRIANGLE_LIST)
 	{
 		if (deviceIdx != 0)

+ 1 - 1
Source/BansheeGLRenderAPI/Source/BsGLCommandBufferManager.cpp

@@ -5,7 +5,7 @@
 
 namespace BansheeEngine
 {
-	SPtr<CommandBuffer> GLCommandBufferManager::createInternal(UINT32 id, CommandBufferType type, UINT32 deviceIdx, 
+	SPtr<CommandBuffer> GLCommandBufferManager::createInternal(UINT32 id, GpuQueueType type, UINT32 deviceIdx,
 		UINT32 queueIdx, bool secondary)
 	{
 		CommandBuffer* buffer = new (bs_alloc<GLCommandBuffer>()) GLCommandBuffer(id, type, deviceIdx, queueIdx, secondary);

+ 16 - 7
Source/BansheeVulkanRenderAPI/Include/BsVulkanCommandBuffer.h

@@ -25,19 +25,26 @@ namespace BansheeEngine
 		~VulkanCmdBufferPool();
 
 		/** Attempts to find a free command buffer, or creates a new one if not found. */
-		VulkanCmdBuffer* getBuffer(CommandBufferType type, UINT32 queueIdx, bool secondary);
+		VulkanCmdBuffer* getBuffer(GpuQueueType type, UINT32 queueIdx, bool secondary);
 
 	private:
+		/** Command buffer pool and related information. */
+		struct PoolInfo
+		{
+			VkCommandPool pool = VK_NULL_HANDLE;
+			UINT32 queueFamily = -1;
+		};
+
 		/** Creates a new command buffer. */
-		VulkanCmdBuffer* createBuffer(VulkanQueueType type, bool secondary);
+		VulkanCmdBuffer* createBuffer(GpuQueueType type, bool secondary);
 
 		/** Returns a Vulkan command pool for the specified queue type. */
-		VkCommandPool getPool(VulkanQueueType type);
+		const PoolInfo& getPool(GpuQueueType type);
 
 		VulkanDevice& mDevice;
-		VkCommandPool mPools[VQT_COUNT];
+		PoolInfo mPools[GQT_COUNT];
 
-		VulkanCmdBuffer* mBuffers[VQT_COUNT][BS_MAX_QUEUES_PER_TYPE][BS_MAX_VULKAN_COMMAND_BUFFERS_PER_QUEUE];
+		VulkanCmdBuffer* mBuffers[GQT_COUNT][BS_MAX_QUEUES_PER_TYPE][BS_MAX_VULKAN_COMMAND_BUFFERS_PER_QUEUE];
 		UINT32 mNextId;
 	};
 
@@ -63,7 +70,7 @@ namespace BansheeEngine
 		};
 
 	public:
-		VulkanCmdBuffer(VulkanDevice& device, UINT32 id, VkCommandPool pool, bool secondary);
+		VulkanCmdBuffer(VulkanDevice& device, UINT32 id, VkCommandPool pool, UINT32 queueFamily, bool secondary);
 		~VulkanCmdBuffer();
 
 		/** Returns an unique identifier of this command buffer. */
@@ -125,6 +132,7 @@ namespace BansheeEngine
 		void notifySubmit();
 
 		UINT32 mId;
+		UINT32 mQueueFamily;
 		State mState;
 		VulkanDevice& mDevice;
 		VkCommandPool mPool;
@@ -154,7 +162,7 @@ namespace BansheeEngine
 	private:
 		friend class VulkanCommandBufferManager;
 
-		VulkanCommandBuffer(VulkanDevice& device, UINT32 id, CommandBufferType type, UINT32 deviceIdx, UINT32 queueIdx, 
+		VulkanCommandBuffer(VulkanDevice& device, UINT32 id, GpuQueueType type, UINT32 deviceIdx, UINT32 queueIdx,
 			bool secondary);
 
 		/** 
@@ -167,6 +175,7 @@ namespace BansheeEngine
 		VulkanCmdBuffer* mSubmittedBuffer;
 		VulkanDevice& mDevice;
 		VulkanQueue* mQueue;
+		UINT32 mIdMask;
 
 		VkSemaphore mSemaphoresTemp[BS_MAX_COMMAND_BUFFERS];
 	};

+ 1 - 1
Source/BansheeVulkanRenderAPI/Include/BsVulkanCommandBufferManager.h

@@ -23,7 +23,7 @@ namespace BansheeEngine
 		~VulkanCommandBufferManager();
 
 		/** @copydoc CommandBufferManager::createInternal() */
-		SPtr<CommandBuffer> createInternal(UINT32 id, CommandBufferType type, UINT32 deviceIdx = 0, UINT32 queueIdx = 0,
+		SPtr<CommandBuffer> createInternal(UINT32 id, GpuQueueType type, UINT32 deviceIdx = 0, UINT32 queueIdx = 0,
 			bool secondary = false) override;
 
 		/** 

+ 4 - 4
Source/BansheeVulkanRenderAPI/Include/BsVulkanDevice.h

@@ -35,16 +35,16 @@ namespace BansheeEngine
 		const VkPhysicalDeviceMemoryProperties& getMemoryProperties() const { return mMemoryProperties; }
 
 		/** Returns the number of queue supported on the device, per type. */
-		UINT32 getNumQueues(VulkanQueueType type) const { return (UINT32)mQueueInfos[(int)type].queues.size(); }
+		UINT32 getNumQueues(GpuQueueType type) const { return (UINT32)mQueueInfos[(int)type].queues.size(); }
 
 		/** Returns queue of the specified type at the specified index. Index must be in range [0, getNumQueues()). */
-		VulkanQueue* getQueue(VulkanQueueType type, UINT32 idx) const { return mQueueInfos[(int)type].queues[idx]; }
+		VulkanQueue* getQueue(GpuQueueType type, UINT32 idx) const { return mQueueInfos[(int)type].queues[idx]; }
 
 		/** 
 		 * Returns index of the queue family for the specified queue type. Returns -1 if no queues for the specified type 
 		 * exist. There will always be a queue family for the graphics type.
 		 */
-		UINT32 getQueueFamily(VulkanQueueType type) const { return mQueueInfos[(int)type].familyIdx; }
+		UINT32 getQueueFamily(GpuQueueType type) const { return mQueueInfos[(int)type].familyIdx; }
 
 		/** Returns a pool that can be used for allocating command buffers for all queues on this device. */
 		VulkanCmdBufferPool& getCmdBufferPool() const { return *mCommandBufferPool; }
@@ -98,7 +98,7 @@ namespace BansheeEngine
 			Vector<VulkanQueue*> queues;
 		};
 
-		QueueInfo mQueueInfos[VQT_COUNT];
+		QueueInfo mQueueInfos[GQT_COUNT];
 
 	};
 

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

@@ -52,21 +52,6 @@ namespace BansheeEngine
 	{
 		RenderStatObject_PipelineState = 100
 	};
-
-	/** Types of GPU queues. */
-	enum VulkanQueueType
-	{
-		/**
-		 * Queue used for rendering. Allows the use of draw commands, but also all commands supported by compute
-		 * or upload buffers.
-		 */
-		VQT_GRAPHICS,
-		/** Discrete queue used for compute operations. Allows the use of dispatch and upload commands. */
-		VQT_COMPUTE,
-		/** Queue used for memory transfer operations only. No rendering or compute dispatch allowed. */
-		VQT_UPLOAD,
-		VQT_COUNT // Keep at end
-	};
 }
 
 /** Macro to get a procedure address based on a Vulkan instance. */

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

@@ -55,9 +55,6 @@ namespace BansheeEngine
 		/** Gets Vulkan flags representing the number of samples in an image. Sample count must be a power of 2. */
 		static VkSampleCountFlagBits getSampleFlags(UINT32 numSamples);
 
-		/** Converts between a command buffer type and a Vulkan queue type. */
-		static VulkanQueueType getQueueType(CommandBufferType type);
-
 		/** 
 		 * Populates the provided array with Vulkan devices that correspond to provided flags. Sets null in unused slots. 
 		 */

+ 38 - 30
Source/BansheeVulkanRenderAPI/Source/BsVulkanCommandBuffer.cpp

@@ -11,9 +11,9 @@ namespace BansheeEngine
 	VulkanCmdBufferPool::VulkanCmdBufferPool(VulkanDevice& device)
 		:mDevice(device), mPools{}, mBuffers {}, mNextId(1)
 	{
-		for (UINT32 i = 0; i < VQT_COUNT; i++)
+		for (UINT32 i = 0; i < GQT_COUNT; i++)
 		{
-			UINT32 familyIdx = device.getQueueFamily((VulkanQueueType)i);
+			UINT32 familyIdx = device.getQueueFamily((GpuQueueType)i);
 
 			if (familyIdx == (UINT32)-1)
 				continue;
@@ -24,13 +24,14 @@ namespace BansheeEngine
 			poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
 			poolInfo.queueFamilyIndex = familyIdx;
 
-			vkCreateCommandPool(device.getLogical(), &poolInfo, gVulkanAllocator, &mPools[i]);
+			mPools[i].queueFamily = familyIdx;
+			vkCreateCommandPool(device.getLogical(), &poolInfo, gVulkanAllocator, &mPools[i].pool);
 		}
 	}
 
 	VulkanCmdBufferPool::~VulkanCmdBufferPool()
 	{
-		for (UINT32 i = 0; i < VQT_COUNT; i++)
+		for (UINT32 i = 0; i < GQT_COUNT; i++)
 		{
 			for(UINT32 j = 0; j < BS_MAX_QUEUES_PER_TYPE; j++)
 			{
@@ -45,21 +46,20 @@ namespace BansheeEngine
 			}
 		}
 
-		for (UINT32 i = 0; i < VQT_COUNT; i++)
+		for (UINT32 i = 0; i < GQT_COUNT; i++)
 		{
-			if (mPools[i] == VK_NULL_HANDLE)
+			if (mPools[i].pool == VK_NULL_HANDLE)
 				continue;
 
-			vkDestroyCommandPool(mDevice.getLogical(), mPools[i], gVulkanAllocator);
+			vkDestroyCommandPool(mDevice.getLogical(), mPools[i].pool, gVulkanAllocator);
 		}
 	}
 
-	VulkanCmdBuffer* VulkanCmdBufferPool::getBuffer(CommandBufferType type, UINT32 queueIdx, bool secondary)
+	VulkanCmdBuffer* VulkanCmdBufferPool::getBuffer(GpuQueueType type, UINT32 queueIdx, bool secondary)
 	{
 		assert(queueIdx < BS_MAX_QUEUES_PER_TYPE);
 
-		VulkanQueueType queueType = VulkanUtility::getQueueType(type);
-		VulkanCmdBuffer** buffers = mBuffers[queueType][queueIdx];
+		VulkanCmdBuffer** buffers = mBuffers[type][queueIdx];
 
 		UINT32 i = 0;
 		for(; i < BS_MAX_VULKAN_COMMAND_BUFFERS_PER_QUEUE; i++)
@@ -77,30 +77,30 @@ namespace BansheeEngine
 		assert(i < BS_MAX_VULKAN_COMMAND_BUFFERS_PER_QUEUE && 
 			"Too many command buffers allocated. Increment BS_MAX_VULKAN_COMMAND_BUFFERS_PER_QUEUE to a higher value. ");
 
-		buffers[i] = createBuffer(queueType, secondary);
+		buffers[i] = createBuffer(type, secondary);
 		buffers[i]->begin();
 
 		return buffers[i];
 	}
 
-	VulkanCmdBuffer* VulkanCmdBufferPool::createBuffer(VulkanQueueType type, bool secondary)
+	VulkanCmdBuffer* VulkanCmdBufferPool::createBuffer(GpuQueueType type, bool secondary)
 	{
-		VkCommandPool pool = getPool(type);
+		const PoolInfo& poolInfo = getPool(type);
 
-		return bs_new<VulkanCmdBuffer>(mDevice, mNextId++, pool, secondary);
+		return bs_new<VulkanCmdBuffer>(mDevice, mNextId++, poolInfo.pool, poolInfo.queueFamily, secondary);
 	}
 
-	VkCommandPool VulkanCmdBufferPool::getPool(VulkanQueueType type)
+	const VulkanCmdBufferPool::PoolInfo& VulkanCmdBufferPool::getPool(GpuQueueType type)
 	{
-		VkCommandPool pool = mPools[type];
-		if (pool == VK_NULL_HANDLE)
-			pool = mPools[VQT_GRAPHICS]; // Graphics queue is guaranteed to exist
+		const PoolInfo* poolInfo = &mPools[type];
+		if (poolInfo->pool == VK_NULL_HANDLE)
+			poolInfo = &mPools[GQT_GRAPHICS]; // Graphics queue is guaranteed to exist
 
-		return pool;
+		return *poolInfo;
 	}
 
-	VulkanCmdBuffer::VulkanCmdBuffer(VulkanDevice& device, UINT32 id, VkCommandPool pool, bool secondary)
-		:mId(id), mState(State::Ready), mDevice(device), mPool(pool), mFenceCounter(0)
+	VulkanCmdBuffer::VulkanCmdBuffer(VulkanDevice& device, UINT32 id, VkCommandPool pool, UINT32 queueFamily, bool secondary)
+		:mId(id), mQueueFamily(queueFamily), mState(State::Ready), mDevice(device), mPool(pool), mFenceCounter(0)
 	{
 		VkCommandBufferAllocateInfo cmdBufferAllocInfo;
 		cmdBufferAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
@@ -236,20 +236,28 @@ namespace BansheeEngine
 			entry.first->notifyUsed(*this, entry.second.flags);
 	}
 
-	VulkanCommandBuffer::VulkanCommandBuffer(VulkanDevice& device, UINT32 id, CommandBufferType type, UINT32 deviceIdx,
+	VulkanCommandBuffer::VulkanCommandBuffer(VulkanDevice& device, UINT32 id, GpuQueueType type, UINT32 deviceIdx,
 		UINT32 queueIdx, bool secondary)
 		: CommandBuffer(id, type, deviceIdx, queueIdx, secondary), mBuffer(nullptr), mSubmittedBuffer(nullptr)
-		, mDevice(device), mQueue(nullptr)
+		, mDevice(device), mQueue(nullptr), mIdMask(0)
 	{
-		VulkanQueueType queueType =  VulkanUtility::getQueueType(mType);
+		GpuQueueType queueType = mType;
 
 		UINT32 numQueues = device.getNumQueues(queueType);
-		if (numQueues > 0)
-			mQueue = device.getQueue(queueType, mQueueIdx % numQueues);
-		else // Fallback to graphics queue
+		if (numQueues == 0) // Fallback to graphics queue
 		{
-			numQueues = device.getNumQueues(VQT_GRAPHICS);
-			mQueue = device.getQueue(VQT_GRAPHICS, mQueueIdx % numQueues);
+			queueType = GQT_GRAPHICS;
+			numQueues = device.getNumQueues(GQT_GRAPHICS);
+		}
+
+		mQueue = device.getQueue(queueType, mQueueIdx % numQueues);
+
+		// If multiple command buffer IDs map to the same queue, mark them in the mask
+		UINT32 curIdx = mQueueIdx;
+		while (curIdx < BS_MAX_QUEUES_PER_TYPE)
+		{
+			mIdMask |= CommandSyncMask::getGlobalQueueIdx(queueType, curIdx);
+			curIdx += numQueues;
 		}
 
 		acquireNewBuffer();
@@ -293,7 +301,7 @@ namespace BansheeEngine
 		submitInfo.pSignalSemaphores = &signalSemaphore;
 
 		// Ignore myself
-		syncMask &= ~mId;
+		syncMask &= ~mIdMask;
 
 		VulkanCommandBufferManager& cmdBufManager = static_cast<VulkanCommandBufferManager&>(CommandBufferManager::instance());
 		cmdBufManager.getSyncSemaphores(mDeviceIdx, syncMask, mSemaphoresTemp, submitInfo.waitSemaphoreCount);

+ 6 - 4
Source/BansheeVulkanRenderAPI/Source/BsVulkanCommandBufferManager.cpp

@@ -15,7 +15,7 @@ namespace BansheeEngine
 		
 	}
 
-	SPtr<CommandBuffer> VulkanCommandBufferManager::createInternal(UINT32 id, CommandBufferType type, UINT32 deviceIdx, 
+	SPtr<CommandBuffer> VulkanCommandBufferManager::createInternal(UINT32 id, GpuQueueType type, UINT32 deviceIdx,
 		UINT32 queueIdx, bool secondary)
 	{
 		UINT32 numDevices = mRapi._getNumDevices();
@@ -43,13 +43,15 @@ namespace BansheeEngine
 		UINT32 semaphoreIdx = 0;
 		for (UINT32 i = 0; i < BS_MAX_COMMAND_BUFFERS; i++)
 		{
-			if ((syncMask & (1 << i)) == 0) // We don't care about the command buffer
-				continue;
-
 			if (mActiveCommandBuffers[deviceIdx][i] == nullptr) // Command buffer doesn't exist
 				continue;
 
 			VulkanCommandBuffer* cmdBuffer = static_cast<VulkanCommandBuffer*>(mActiveCommandBuffers[deviceIdx][i]);
+			UINT32 globalQueueIdx = CommandSyncMask::getGlobalQueueIdx(cmdBuffer->getType(), cmdBuffer->getQueueIdx());
+
+			if ((syncMask & (1 << globalQueueIdx)) == 0) // We don't care about the command buffer
+				continue;
+			
 			VulkanCmdBuffer* lowLevelCmdBuffer = cmdBuffer->mSubmittedBuffer;
 
 			if (lowLevelCmdBuffer == nullptr || !lowLevelCmdBuffer->isSubmitted()) // If not submitted, no need to sync with it

+ 7 - 7
Source/BansheeVulkanRenderAPI/Source/BsVulkanDevice.cpp

@@ -11,7 +11,7 @@ namespace BansheeEngine
 		:mPhysicalDevice(device), mLogicalDevice(nullptr), mQueueInfos{}
 	{
 		// Set to default
-		for (UINT32 i = 0; i < VQT_COUNT; i++)
+		for (UINT32 i = 0; i < GQT_COUNT; i++)
 			mQueueInfos[i].familyIdx = (UINT32)-1;
 
 		vkGetPhysicalDeviceProperties(device, &mDeviceProperties);
@@ -28,7 +28,7 @@ namespace BansheeEngine
 		const float defaultQueuePriorities[BS_MAX_QUEUES_PER_TYPE] = { 0.0f };
 		Vector<VkDeviceQueueCreateInfo> queueCreateInfos;
 
-		auto populateQueueInfo = [&](VulkanQueueType type, uint32_t familyIdx)
+		auto populateQueueInfo = [&](GpuQueueType type, uint32_t familyIdx)
 		{
 			queueCreateInfos.push_back(VkDeviceQueueCreateInfo());
 
@@ -49,7 +49,7 @@ namespace BansheeEngine
 		{
 			if ((queueFamilyProperties[i].queueFlags & VK_QUEUE_COMPUTE_BIT) && (queueFamilyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0)
 			{
-				populateQueueInfo(VQT_COMPUTE, i);
+				populateQueueInfo(GQT_COMPUTE, i);
 				break;
 			}
 		}
@@ -61,7 +61,7 @@ namespace BansheeEngine
 				((queueFamilyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0) &&
 				((queueFamilyProperties[i].queueFlags & VK_QUEUE_COMPUTE_BIT) == 0))
 			{
-				populateQueueInfo(VQT_UPLOAD, i);
+				populateQueueInfo(GQT_UPLOAD, i);
 				break;
 			}
 		}
@@ -71,7 +71,7 @@ namespace BansheeEngine
 		{
 			if (queueFamilyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
 			{
-				populateQueueInfo(VQT_GRAPHICS, i);
+				populateQueueInfo(GQT_GRAPHICS, i);
 				break;
 			}
 		}
@@ -96,7 +96,7 @@ namespace BansheeEngine
 		assert(result == VK_SUCCESS);
 
 		// Retrieve queues
-		for(UINT32 i = 0; i < VQT_COUNT; i++)
+		for(UINT32 i = 0; i < GQT_COUNT; i++)
 		{
 			UINT32 numQueues = (UINT32)mQueueInfos[i].queues.size();
 			for (UINT32 j = 0; j < numQueues; j++)
@@ -118,7 +118,7 @@ namespace BansheeEngine
 	{
 		vkDeviceWaitIdle(mLogicalDevice);
 
-		for (UINT32 i = 0; i < VQT_COUNT; i++)
+		for (UINT32 i = 0; i < GQT_COUNT; i++)
 		{
 			UINT32 numQueues = (UINT32)mQueueInfos[i].queues.size();
 			for (UINT32 j = 0; j < numQueues; j++)

+ 0 - 16
Source/BansheeVulkanRenderAPI/Source/BsVulkanUtility.cpp

@@ -403,22 +403,6 @@ namespace BansheeEngine
 		return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
 	}
 
-	VulkanQueueType VulkanUtility::getQueueType(CommandBufferType type)
-	{
-		switch(type)
-		{
-		case CBT_GRAPHICS:
-			return VQT_GRAPHICS;
-		case CBT_COMPUTE:
-			return VQT_COMPUTE;
-		case CBT_UPLOAD:
-			return VQT_UPLOAD;
-		}
-
-		// Unsupported type
-		return VQT_GRAPHICS;
-	}
-
 	void VulkanUtility::getDevices(const VulkanRenderAPI& rapi, GpuDeviceFlags flags, VulkanDevice*(&devices)[BS_MAX_LINKED_DEVICES])
 	{
 		if(flags == GDF_DEFAULT)

+ 1 - 1
Source/BansheeVulkanRenderAPI/Source/Win32/BsWin32RenderWindow.cpp

@@ -118,7 +118,7 @@ namespace BansheeEngine
 		SPtr<VulkanDevice> presentDevice = mRenderAPI._getPresentDevice();
 		VkPhysicalDevice physicalDevice = presentDevice->getPhysical();
 
-		UINT32 presentQueueIdx = presentDevice->getQueueFamily(VQT_GRAPHICS);
+		UINT32 presentQueueIdx = presentDevice->getQueueFamily(GQT_GRAPHICS);
 		
 		VkBool32 supportsPresent;
 		vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, presentQueueIdx, mSurface, &supportsPresent);