Преглед изворни кода

Register GPU programs with command buffer, on Vulkan pipeline state bind

BearishSun пре 9 година
родитељ
комит
2f33441889

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

@@ -62,6 +62,12 @@ namespace bs
 		 */
 		VkPipelineLayout getPipelineLayout(UINT32 deviceIdx) const;
 
+		/** 
+		 * Registers any resources used by the pipeline with the provided command buffer. This should be called whenever
+		 * a pipeline is bound to a command buffer.
+		 */
+		void registerPipelineResources(VulkanCmdBuffer* cmdBuffer);
+
 	protected:
 		friend class VulkanRenderStateCoreManager;
 
@@ -161,6 +167,12 @@ namespace bs
 		 */
 		VkPipelineLayout getPipelineLayout(UINT32 deviceIdx) const;
 
+		/** 
+		 * Registers any resources used by the pipeline with the provided command buffer. This should be called whenever
+		 * a pipeline is bound to a command buffer.
+		 */
+		void registerPipelineResources(VulkanCmdBuffer* cmdBuffer);
+
 	protected:
 		friend class VulkanRenderStateCoreManager;
 

+ 3 - 0
Source/BansheeVulkanRenderAPI/Source/BsVulkanCommandBuffer.cpp

@@ -479,6 +479,7 @@ namespace bs
 		mComputePipeline = nullptr;
 		mGfxPipelineRequiresBind = true;
 		mCmpPipelineRequiresBind = true;
+		mDescriptorSetsBindState = DescriptorSetBindFlag::Graphics | DescriptorSetBindFlag::Compute;
 	}
 
 	void VulkanCmdBuffer::refreshFenceStatus()
@@ -832,6 +833,7 @@ namespace bs
 		if (pipeline == nullptr)
 			return false;
 
+		mGraphicsPipeline->registerPipelineResources(this);
 		registerResource(pipeline, VulkanUseFlag::Read);
 
 		vkCmdBindPipeline(mCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getHandle());
@@ -963,6 +965,7 @@ namespace bs
 				return;
 
 			registerResource(pipeline, VulkanUseFlag::Read);
+			mComputePipeline->registerPipelineResources(this);
 
 			vkCmdBindPipeline(mCmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getHandle());
 			mCmpPipelineRequiresBind = false;

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

@@ -8,6 +8,7 @@
 #include "BsVulkanRenderAPI.h"
 #include "BsVulkanGpuPipelineParamInfo.h"
 #include "BsVulkanVertexInputManager.h"
+#include "BsVulkanCommandBuffer.h"
 #include "BsRasterizerState.h"
 #include "BsDepthStencilState.h"
 #include "BsBlendState.h"
@@ -327,6 +328,30 @@ namespace bs
 		return mPerDeviceData[deviceIdx].pipelineLayout;
 	}
 
+	void VulkanGraphicsPipelineStateCore::registerPipelineResources(VulkanCmdBuffer* cmdBuffer)
+	{
+		UINT32 deviceIdx = cmdBuffer->getDeviceIdx();
+
+		std::array<VulkanGpuProgramCore*, 5> programs = {
+			static_cast<VulkanGpuProgramCore*>(mData.vertexProgram.get()),
+			static_cast<VulkanGpuProgramCore*>(mData.hullProgram.get()),
+			static_cast<VulkanGpuProgramCore*>(mData.domainProgram.get()),
+			static_cast<VulkanGpuProgramCore*>(mData.geometryProgram.get()),
+			static_cast<VulkanGpuProgramCore*>(mData.fragmentProgram.get()),
+		};
+
+		for(auto& entry : programs)
+		{
+			if (entry != nullptr)
+			{
+				VulkanShaderModule* module = entry->getShaderModule(deviceIdx);
+
+				if(module != nullptr)
+					cmdBuffer->registerResource(module, VulkanUseFlag::Read);
+			}
+		}
+	}
+
 	VulkanPipeline* VulkanGraphicsPipelineStateCore::createPipeline(UINT32 deviceIdx, VulkanFramebuffer* framebuffer,
 		bool readOnlyDepth, bool preserveContents, DrawOperationType drawOp, const SPtr<VulkanVertexInput>& vertexInput)
 	{
@@ -393,7 +418,13 @@ namespace bs
 				continue;
 
 			VkPipelineShaderStageCreateInfo& stageCI = mShaderStageInfos[stageOutputIdx];
-			stageCI.module = program->getHandle(deviceIdx);
+
+			VulkanShaderModule* module = program->getShaderModule(i);
+
+			if (module != nullptr)
+				stageCI.module = module->getHandle();
+			else
+				stageCI.module = VK_NULL_HANDLE;
 
 			stageOutputIdx++;
 		}
@@ -475,7 +506,13 @@ namespace bs
 				for (UINT32 j = 0; j < numLayouts; j++)
 					layouts[j] = vkParamInfo.getLayout(i, j);
 
-				stageCI.module = vkProgram->getHandle(i);
+				VulkanShaderModule* module = vkProgram->getShaderModule(i);
+
+				if (module != nullptr)
+					stageCI.module = module->getHandle();
+				else
+					stageCI.module = VK_NULL_HANDLE;
+
 				pipelineCI.layout = descManager.getPipelineLayout(layouts, numLayouts);
 
 				VkPipeline pipeline;
@@ -508,4 +545,18 @@ namespace bs
 	{
 		return mPerDeviceData[deviceIdx].pipelineLayout;
 	}
+
+	void VulkanComputePipelineStateCore::registerPipelineResources(VulkanCmdBuffer* cmdBuffer)
+	{
+		UINT32 deviceIdx = cmdBuffer->getDeviceIdx();
+
+		VulkanGpuProgramCore* program = static_cast<VulkanGpuProgramCore*>(mProgram.get());
+		if(program != nullptr)
+		{
+			VulkanShaderModule* module = program->getShaderModule(deviceIdx);
+
+			if (module != nullptr)
+				cmdBuffer->registerResource(module, VulkanUseFlag::Read);
+		}
+	}
 }

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

@@ -557,7 +557,7 @@ namespace bs
 		if (!shader->parse(&resources, 450, false, EShMsgDefault))
 		{
 			mIsCompiled = false;
-			mCompileError = "Compile error: " + toString(shader->getInfoLog());
+			mCompileError = "Compile error: " + String(shader->getInfoLog());
 
 			goto cleanup;
 		}
@@ -567,7 +567,7 @@ namespace bs
 		if (!program->link(EShMsgDefault))
 		{
 			mIsCompiled = false;
-			mCompileError = "Link error: " + toString(program->getInfoLog());
+			mCompileError = "Link error: " + String(program->getInfoLog());
 
 			goto cleanup;
 		}
@@ -598,7 +598,7 @@ namespace bs
 		// Compile shader and create Vulkan module
 		// Note: We provide GLSL code to the driver under the hood instead of using SPIR-V, mainly because of
 		// optimization concerns. Later we can convert to SPIR-V and feed it directly.
-		UINT32 codeSize = source.size() + 3 * sizeof(UINT32);
+		UINT32 codeSize = (UINT32)source.size() + 3 * sizeof(UINT32);
 		UINT32* codeBytes = (UINT32*)bs_stack_alloc(codeSize);
 
 		// Add special header so code is recognized as GLSL