Ver código fonte

Vulkan render API swapBuffers() method hooked up

BearishSun 9 anos atrás
pai
commit
b267abf39a

+ 8 - 7
Source/BansheeCore/Include/BsRenderAPI.h

@@ -383,13 +383,14 @@ namespace BansheeEngine
 		/** 
 		 * Swap the front and back buffer of the specified render target. 
 		 *
-		 * @param[in]	target			Render target to perform the buffer swap on.
-		 * @param[in]	commandBuffer	Optional command buffer to queue the operation on. If not provided operation
-		 *								is executed immediately. Otherwise it is executed when executeCommands() is called.
-		 *								Buffer must support graphics operations.
-		 */
-		virtual void swapBuffers(const SPtr<RenderTargetCore>& target, 
-			const SPtr<CommandBuffer>& commandBuffer = nullptr) = 0;
+		 * @param[in]	target		Render target to perform the buffer swap on.
+		 * @param[in]	syncMask	Optional synchronization mask that determines for which queues should the system wait
+		 *							before performing the swap buffer operation. By default the system waits for all queues.
+		 *							However if certain queues are performing non-rendering operations, or operations not
+		 *							related to the provided render target, you can exclude them from the sync mask for
+		 *							potentially better performance. You can use CommandSyncMask to generate a valid sync mask.
+		 */
+		virtual void swapBuffers(const SPtr<RenderTargetCore>& target, UINT32 syncMask = 0xFFFFFFFF) = 0;
 
 		/**
 		 * Change the render target into which we want to draw.

+ 1 - 1
Source/BansheeCore/Include/BsRenderTarget.h

@@ -223,7 +223,7 @@ namespace BansheeEngine
 		 *
 		 * @param[in]	syncMask	Optional synchronization mask that determines for which queues should the system wait
 		 *							before performing the swap buffer operation. By default the system waits for all queues.
-		 *							Howvever if certain queues are performing non-rendering operations, or operations not 
+		 *							However if certain queues are performing non-rendering operations, or operations not 
 		 *							related to this render target, you can exclude them from the sync mask for potentially 
 		 *							better performance. You can use CommandSyncMask to generate a valid sync mask.
 		 */

+ 1 - 2
Source/BansheeD3D11RenderAPI/Include/BsD3D11RenderAPI.h

@@ -93,8 +93,7 @@ namespace BansheeEngine
 			const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
 
 		/** @copydoc RenderAPICore::swapBuffers() */
-		void swapBuffers(const SPtr<RenderTargetCore>& target,
-			const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
+		void swapBuffers(const SPtr<RenderTargetCore>& target, UINT32 syncMask = 0xFFFFFFFF) override;
 
 		/** @copydoc RenderAPICore::addCommands() */
 		void addCommands(const SPtr<CommandBuffer>& commandBuffer, const SPtr<CommandBuffer>& secondary) override;

+ 4 - 17
Source/BansheeD3D11RenderAPI/Source/BsD3D11RenderAPI.cpp

@@ -1066,24 +1066,11 @@ namespace BansheeEngine
 		BS_INC_RENDER_STAT(NumRenderTargetChanges);
 	}
 
-	void D3D11RenderAPI::swapBuffers(const SPtr<RenderTargetCore>& target, const SPtr<CommandBuffer>& commandBuffer)
+	void D3D11RenderAPI::swapBuffers(const SPtr<RenderTargetCore>& target, UINT32 syncMask)
 	{
-		auto executeRef = [&](const SPtr<RenderTargetCore>& target)
-		{
-			THROW_IF_NOT_CORE_THREAD;
-			target->swapBuffers();
-		};
-
-		if (commandBuffer == nullptr)
-			executeRef(target);
-		else
-		{
-			auto execute = [=]() { executeRef(target); };
-
-			SPtr<D3D11CommandBuffer> cb = std::static_pointer_cast<D3D11CommandBuffer>(commandBuffer);
-			cb->queueCommand(execute);
-		}
-
+		THROW_IF_NOT_CORE_THREAD;
+		target->swapBuffers();
+		
 		BS_INC_RENDER_STAT(NumPresents);
 	}
 

+ 1 - 2
Source/BansheeGLRenderAPI/Include/BsGLRenderAPI.h

@@ -83,8 +83,7 @@ namespace BansheeEngine
 			const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
 
 		/** @copydoc RenderAPICore::swapBuffers() */
-		void swapBuffers(const SPtr<RenderTargetCore>& target,
-			const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
+		void swapBuffers(const SPtr<RenderTargetCore>& target, UINT32 syncMask = 0xFFFFFFFF) override;
 
 		/** @copydoc RenderAPICore::setRenderTarget() */
 		void setRenderTarget(const SPtr<RenderTargetCore>& target, bool readOnlyDepthStencil = false,

+ 4 - 17
Source/BansheeGLRenderAPI/Source/BsGLRenderAPI.cpp

@@ -1131,24 +1131,11 @@ namespace BansheeEngine
 		}
 	}
 
-	void GLRenderAPI::swapBuffers(const SPtr<RenderTargetCore>& target, const SPtr<CommandBuffer>& commandBuffer)
+	void GLRenderAPI::swapBuffers(const SPtr<RenderTargetCore>& target, UINT32 syncMask)
 	{
-		auto executeRef = [&](const SPtr<RenderTargetCore>& target)
-		{
-			THROW_IF_NOT_CORE_THREAD;
-			target->swapBuffers();
-		};
-
-		if (commandBuffer == nullptr)
-			executeRef(target);
-		else
-		{
-			auto execute = [=]() { executeRef(target); };
-
-			SPtr<GLCommandBuffer> cb = std::static_pointer_cast<GLCommandBuffer>(commandBuffer);
-			cb->queueCommand(execute);
-		}
-
+		THROW_IF_NOT_CORE_THREAD;
+		target->swapBuffers();
+	
 		BS_INC_RENDER_STAT(NumPresents);
 	}
 

+ 1 - 2
Source/BansheeVulkanRenderAPI/Include/BsVulkanRenderAPI.h

@@ -93,8 +93,7 @@ namespace BansheeEngine
 			const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
 
 		/** @copydoc RenderAPICore::swapBuffers() */
-		void swapBuffers(const SPtr<RenderTargetCore>& target,
-			const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
+		void swapBuffers(const SPtr<RenderTargetCore>& target, UINT32 syncMask = 0xFFFFFFFF) override;
 
 		/** @copydoc RenderAPICore::addCommands() */
 		void addCommands(const SPtr<CommandBuffer>& commandBuffer, const SPtr<CommandBuffer>& secondary) override;

+ 100 - 13
Source/BansheeVulkanRenderAPI/Source/BsVulkanRenderAPI.cpp

@@ -302,12 +302,16 @@ namespace BansheeEngine
 	void VulkanRenderAPI::setGraphicsPipeline(const SPtr<GpuPipelineStateCore>& pipelineState,
 		const SPtr<CommandBuffer>& commandBuffer)
 	{
+		// TODO
+
 		BS_INC_RENDER_STAT(NumPipelineStateChanges);
 	}
 
 	void VulkanRenderAPI::setComputePipeline(const SPtr<GpuProgramCore>& computeProgram,
 		const SPtr<CommandBuffer>& commandBuffer)
 	{
+		// TODO
+
 		BS_INC_RENDER_STAT(NumPipelineStateChanges);
 	}
 
@@ -333,29 +337,33 @@ namespace BansheeEngine
 
 	void VulkanRenderAPI::setViewport(const Rect2& vp, const SPtr<CommandBuffer>& commandBuffer)
 	{
-		
+		// TODO
 	}
 
 	void VulkanRenderAPI::setVertexBuffers(UINT32 index, SPtr<VertexBufferCore>* buffers, UINT32 numBuffers,
 		const SPtr<CommandBuffer>& commandBuffer)
 	{
+		// TODO
+
 		BS_INC_RENDER_STAT(NumVertexBufferBinds);
 	}
 
 	void VulkanRenderAPI::setIndexBuffer(const SPtr<IndexBufferCore>& buffer, const SPtr<CommandBuffer>& commandBuffer)
 	{
+		// TODO
+
 		BS_INC_RENDER_STAT(NumIndexBufferBinds);
 	}
 
 	void VulkanRenderAPI::setVertexDeclaration(const SPtr<VertexDeclarationCore>& vertexDeclaration,
 		const SPtr<CommandBuffer>& commandBuffer)
 	{
-		
+		// TODO
 	}
 
 	void VulkanRenderAPI::setDrawOperation(DrawOperationType op, const SPtr<CommandBuffer>& commandBuffer)
 	{
-		
+		// TODO
 	}
 
 	void VulkanRenderAPI::draw(UINT32 vertexOffset, UINT32 vertexCount, UINT32 instanceCount,
@@ -363,6 +371,8 @@ namespace BansheeEngine
 	{
 		UINT32 primCount = 0;
 
+		// TODO
+
 		BS_INC_RENDER_STAT(NumDrawCalls);
 		BS_ADD_RENDER_STAT(NumVertices, vertexCount);
 		BS_ADD_RENDER_STAT(NumPrimitives, primCount);
@@ -373,6 +383,8 @@ namespace BansheeEngine
 	{
 		UINT32 primCount = 0;
 
+		// TODO
+
 		BS_INC_RENDER_STAT(NumDrawCalls);
 		BS_ADD_RENDER_STAT(NumVertices, vertexCount);
 		BS_ADD_RENDER_STAT(NumPrimitives, primCount);
@@ -381,56 +393,64 @@ namespace BansheeEngine
 	void VulkanRenderAPI::dispatchCompute(UINT32 numGroupsX, UINT32 numGroupsY, UINT32 numGroupsZ,
 		const SPtr<CommandBuffer>& commandBuffer)
 	{
+		// TODO
+
 		BS_INC_RENDER_STAT(NumComputeCalls);
 	}
 
 	void VulkanRenderAPI::setScissorRect(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom,
 		const SPtr<CommandBuffer>& commandBuffer)
 	{
-		
+		// TODO
 	}
 
 	void VulkanRenderAPI::setStencilRef(UINT32 value, const SPtr<CommandBuffer>& commandBuffer)
 	{
-		
+		// TODO
 	}
 
 	void VulkanRenderAPI::clearViewport(UINT32 buffers, const Color& color, float depth, UINT16 stencil, UINT8 targetMask,
 		const SPtr<CommandBuffer>& commandBuffer)
 	{
+		// TODO
+
 		BS_INC_RENDER_STAT(NumClears);
 	}
 
 	void VulkanRenderAPI::clearRenderTarget(UINT32 buffers, const Color& color, float depth, UINT16 stencil,
 		UINT8 targetMask, const SPtr<CommandBuffer>& commandBuffer)
 	{
+		// TODO
+
 		BS_INC_RENDER_STAT(NumClears);
 	}
 
 	void VulkanRenderAPI::setRenderTarget(const SPtr<RenderTargetCore>& target, bool readOnlyDepthStencil,
 		const SPtr<CommandBuffer>& commandBuffer)
 	{
+		// TODO
+		
 		BS_INC_RENDER_STAT(NumRenderTargetChanges);
 	}
 
-	void VulkanRenderAPI::swapBuffers(const SPtr<RenderTargetCore>& target, const SPtr<CommandBuffer>& commandBuffer)
+	void VulkanRenderAPI::swapBuffers(const SPtr<RenderTargetCore>& target, UINT32 syncMask)
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
-		VulkanCommandBuffer* cb = getCB(commandBuffer);
-
-		// TODO - Actually swap buffers
+		target->swapBuffers(syncMask);
 
 		// See if any command buffers finished executing
 		VulkanCommandBufferManager& cbm = static_cast<VulkanCommandBufferManager&>(CommandBufferManager::instance());
-		cbm.refreshStates(cb->getDeviceIdx());
+		
+		for (UINT32 i = 0; i < (UINT32)mDevices.size(); i++)
+			cbm.refreshStates(i);
 
 		BS_INC_RENDER_STAT(NumPresents);
 	}
 
 	void VulkanRenderAPI::addCommands(const SPtr<CommandBuffer>& commandBuffer, const SPtr<CommandBuffer>& secondary)
 	{
-
+		BS_EXCEPT(NotImplementedException, "Secondary command buffers not implemented");
 	}
 
 	void VulkanRenderAPI::executeCommands(const SPtr<CommandBuffer>& commandBuffer, UINT32 syncMask)
@@ -446,12 +466,18 @@ namespace BansheeEngine
 	
 	void VulkanRenderAPI::convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest)
 	{
+		dest = matrix;
 
+		// Convert depth range from [-1,1] to [0,1]
+		dest[2][0] = (dest[2][0] + dest[3][0]) / 2;
+		dest[2][1] = (dest[2][1] + dest[3][1]) / 2;
+		dest[2][2] = (dest[2][2] + dest[3][2]) / 2;
+		dest[2][3] = (dest[2][3] + dest[3][3]) / 2;
 	}
 
 	const RenderAPIInfo& VulkanRenderAPI::getAPIInfo() const
 	{
-		static RenderAPIInfo info(0.0f, 0.0f, 0.0f, 1.0f, VET_COLOR_ABGR, false, true, false, false);
+		static RenderAPIInfo info(0.0f, 0.0f, 0.0f, 1.0f, VET_COLOR_ABGR, false, true, true, true);
 
 		return info;
 	}
@@ -459,7 +485,68 @@ namespace BansheeEngine
 	GpuParamBlockDesc VulkanRenderAPI::generateParamBlockDesc(const String& name, Vector<GpuParamDataDesc>& params)
 	{
 		GpuParamBlockDesc block;
-		
+		block.blockSize = 0;
+		block.isShareable = true;
+		block.name = name;
+		block.slot = 0;
+		block.set = 0;
+
+		for (auto& param : params)
+		{
+			const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[param.type];
+			UINT32 size = typeInfo.size / 4;
+			UINT32 alignment = typeInfo.alignment / 4;
+
+			// Fix alignment if needed
+			UINT32 alignOffset = block.blockSize % alignment;
+			if (alignOffset != 0)
+			{
+				UINT32 padding = (alignment - alignOffset);
+				block.blockSize += padding;
+			}
+
+			if (param.arraySize > 1)
+			{
+				// Array elements are always padded and aligned to vec4
+				alignOffset = size % typeInfo.baseTypeSize;
+				if (alignOffset != 0)
+				{
+					UINT32 padding = (typeInfo.baseTypeSize - alignOffset);
+					size += padding;
+				}
+
+				alignOffset = block.blockSize % typeInfo.baseTypeSize;
+				if (alignOffset != 0)
+				{
+					UINT32 padding = (typeInfo.baseTypeSize - alignOffset);
+					block.blockSize += padding;
+				}
+
+				param.elementSize = size;
+				param.arrayElementStride = size;
+				param.cpuMemOffset = block.blockSize;
+				param.gpuMemOffset = 0;
+
+				block.blockSize += size * param.arraySize;
+			}
+			else
+			{
+				param.elementSize = size;
+				param.arrayElementStride = size;
+				param.cpuMemOffset = block.blockSize;
+				param.gpuMemOffset = 0;
+
+				block.blockSize += size;
+			}
+
+			param.paramBlockSlot = 0;
+			param.paramBlockSet = 0;
+		}
+
+		// Constant buffer size must always be a multiple of 16
+		if (block.blockSize % 4 != 0)
+			block.blockSize += (4 - (block.blockSize % 4));
+
 		return block;
 	}