瀏覽代碼

Adding checks to see if a pipeline perform only read operations or color or depth attachments

BearishSun 9 年之前
父節點
當前提交
3ca0661c4f

+ 10 - 0
Source/BansheeVulkanRenderAPI/Include/BsVulkanGpuPipelineState.h

@@ -16,14 +16,24 @@ namespace bs
 	class VulkanPipeline : public VulkanResource
 	class VulkanPipeline : public VulkanResource
 	{
 	{
 	public:
 	public:
+		VulkanPipeline(VulkanResourceManager* owner, VkPipeline pipeline, 
+			const std::array<bool, BS_MAX_MULTIPLE_RENDER_TARGETS>& colorReadOnly, bool depthStencilReadOnly);
 		VulkanPipeline(VulkanResourceManager* owner, VkPipeline pipeline);
 		VulkanPipeline(VulkanResourceManager* owner, VkPipeline pipeline);
 		~VulkanPipeline();
 		~VulkanPipeline();
 
 
 		/** Returns the internal handle to the Vulkan object. */
 		/** Returns the internal handle to the Vulkan object. */
 		VkPipeline getHandle() const { return mPipeline; }
 		VkPipeline getHandle() const { return mPipeline; }
 
 
+		/** Checks is the specified color attachment read-only. Only relevant for graphics pipelines. */
+		bool isColorReadOnly(UINT32 colorIdx) const { return mReadOnlyColor[colorIdx]; }
+
+		/** Checks is the depth-stencil attachment read-only. Only relevant for graphics pipelines. */
+		bool isDepthStencilReadOnly() const { return mReadOnlyDepthStencil; }
 	private:
 	private:
 		VkPipeline mPipeline;
 		VkPipeline mPipeline;
+
+		std::array<bool, BS_MAX_MULTIPLE_RENDER_TARGETS> mReadOnlyColor;
+		bool mReadOnlyDepthStencil;
 	};
 	};
 
 
 	/**	Vulkan implementation of a graphics pipeline state. */
 	/**	Vulkan implementation of a graphics pipeline state. */

+ 33 - 2
Source/BansheeVulkanRenderAPI/Source/BsVulkanGpuPipelineState.cpp

@@ -16,8 +16,14 @@
 
 
 namespace bs
 namespace bs
 {
 {
+	VulkanPipeline::VulkanPipeline(VulkanResourceManager* owner, VkPipeline pipeline, 
+		const std::array<bool, BS_MAX_MULTIPLE_RENDER_TARGETS>& colorReadOnly, bool depthStencilReadOnly)
+		: VulkanResource(owner, true), mPipeline(pipeline), mReadOnlyColor(colorReadOnly)
+		, mReadOnlyDepthStencil(depthStencilReadOnly)
+	{ }
+
 	VulkanPipeline::VulkanPipeline(VulkanResourceManager* owner, VkPipeline pipeline)
 	VulkanPipeline::VulkanPipeline(VulkanResourceManager* owner, VkPipeline pipeline)
-		:VulkanResource(owner, true), mPipeline(pipeline)
+		: VulkanResource(owner, true), mPipeline(pipeline), mReadOnlyColor(), mReadOnlyDepthStencil(false)
 	{ }
 	{ }
 
 
 	VulkanPipeline::~VulkanPipeline()
 	VulkanPipeline::~VulkanPipeline()
@@ -396,16 +402,41 @@ namespace bs
 		mPipelineInfo.layout = mPerDeviceData[deviceIdx].pipelineLayout;
 		mPipelineInfo.layout = mPerDeviceData[deviceIdx].pipelineLayout;
 		mPipelineInfo.pVertexInputState = vertexInput->getCreateInfo();
 		mPipelineInfo.pVertexInputState = vertexInput->getCreateInfo();
 
 
+		bool depthStencilReadOnly;
 		if (framebuffer->hasDepthAttachment())
 		if (framebuffer->hasDepthAttachment())
+		{
 			mPipelineInfo.pDepthStencilState = &mDepthStencilInfo;
 			mPipelineInfo.pDepthStencilState = &mDepthStencilInfo;
+
+			depthStencilReadOnly = !enableDepthWrites;
+		}
 		else
 		else
+		{
 			mPipelineInfo.pDepthStencilState = nullptr;
 			mPipelineInfo.pDepthStencilState = nullptr;
+			depthStencilReadOnly = true;
+		}
 
 
+		std::array<bool, BS_MAX_MULTIPLE_RENDER_TARGETS> colorReadOnly;
 		if (framebuffer->getNumColorAttachments() > 0)
 		if (framebuffer->getNumColorAttachments() > 0)
+		{
 			mPipelineInfo.pColorBlendState = &mColorBlendStateInfo;
 			mPipelineInfo.pColorBlendState = &mColorBlendStateInfo;
+
+			for (UINT32 i = 0; i < BS_MAX_MULTIPLE_RENDER_TARGETS; i++)
+			{
+				VkPipelineColorBlendAttachmentState& blendState = mAttachmentBlendStates[i];
+				colorReadOnly[i] = blendState.colorWriteMask == 0;
+			}
+		}
 		else
 		else
+		{
 			mPipelineInfo.pColorBlendState = nullptr;
 			mPipelineInfo.pColorBlendState = nullptr;
 
 
+			for (UINT32 i = 0; i < BS_MAX_MULTIPLE_RENDER_TARGETS; i++)
+			{
+				VkPipelineColorBlendAttachmentState& blendState = mAttachmentBlendStates[i];
+				colorReadOnly[i] = true;
+			}
+		}
+
 		std::pair<VkShaderStageFlagBits, GpuProgramCore*> stages[] =
 		std::pair<VkShaderStageFlagBits, GpuProgramCore*> stages[] =
 		{
 		{
 			{ VK_SHADER_STAGE_VERTEX_BIT, mData.vertexProgram.get() },
 			{ VK_SHADER_STAGE_VERTEX_BIT, mData.vertexProgram.get() },
@@ -451,7 +482,7 @@ namespace bs
 		mDepthStencilInfo.back.failOp = oldBackFailOp;
 		mDepthStencilInfo.back.failOp = oldBackFailOp;
 		mDepthStencilInfo.back.depthFailOp = oldBackZFailOp;
 		mDepthStencilInfo.back.depthFailOp = oldBackZFailOp;
 
 
-		return device->getResourceManager().create<VulkanPipeline>(pipeline);
+		return device->getResourceManager().create<VulkanPipeline>(pipeline, colorReadOnly, depthStencilReadOnly);
 	}
 	}
 
 
 	VulkanComputePipelineStateCore::VulkanComputePipelineStateCore(const SPtr<GpuProgramCore>& program, 
 	VulkanComputePipelineStateCore::VulkanComputePipelineStateCore(const SPtr<GpuProgramCore>& program,