浏览代码

Some more work on the Vulkan pipeline

Panagiotis Christopoulos Charitos 9 年之前
父节点
当前提交
82e681f5ff

+ 1 - 1
LICENSE

@@ -1,5 +1,5 @@
 AnKi 3D Engine
 AnKi 3D Engine
-Copyright (c) 2009 - 2015 Panagiotis Christopoulos Charitos.
+Copyright (c) 2009 - 2016 Panagiotis Christopoulos Charitos.
 All rights reserved.
 All rights reserved.
 
 
 Redistribution and use in source and binary forms, with or without
 Redistribution and use in source and binary forms, with or without

+ 2 - 0
include/anki/Config.h.cmake

@@ -127,12 +127,14 @@
 #	define ANKI_RESTRICT __restrict
 #	define ANKI_RESTRICT __restrict
 #	define ANKI_USE_RESULT __attribute__((warn_unused_result))
 #	define ANKI_USE_RESULT __attribute__((warn_unused_result))
 #	define ANKI_FORCE_INLINE __attribute__((always_inline))
 #	define ANKI_FORCE_INLINE __attribute__((always_inline))
+#	define ANKI_UNUSED __attribute__((__unused__))
 #else
 #else
 #	define ANKI_LIKELY(x) ((x) == 1)
 #	define ANKI_LIKELY(x) ((x) == 1)
 #	define ANKI_UNLIKELY(x) ((x) == 1)
 #	define ANKI_UNLIKELY(x) ((x) == 1)
 #	define ANKI_RESTRICT
 #	define ANKI_RESTRICT
 #	define ANKI_USE_RESULT
 #	define ANKI_USE_RESULT
 #	define ANKI_FORCE_INLINE
 #	define ANKI_FORCE_INLINE
+#	define ANKI_UNUSED
 #endif
 #endif
 
 
 #ifdef ANKI_BUILD
 #ifdef ANKI_BUILD

+ 3 - 1
include/anki/gr/Enums.h

@@ -173,7 +173,9 @@ enum class ShaderType : U8
 	FRAGMENT,
 	FRAGMENT,
 	COMPUTE,
 	COMPUTE,
 
 
-	COUNT
+	COUNT,
+	FIRST_GRAPHICS = VERTEX,
+	LAST_GRAPHICS = FRAGMENT,
 };
 };
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(ShaderType, inline)
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(ShaderType, inline)
 
 

+ 1 - 1
include/anki/gr/gl/GlState.h

@@ -120,7 +120,7 @@ private:
 
 
 	class alignas(16) Aligned16Type
 	class alignas(16) Aligned16Type
 	{
 	{
-		U8 _m_val[16];
+		U8 _m_val[16] ANKI_UNUSED;
 	};
 	};
 
 
 	DArray<Aligned16Type> m_transferBuffer;
 	DArray<Aligned16Type> m_transferBuffer;

+ 7 - 0
include/anki/gr/vulkan/Common.h

@@ -29,6 +29,13 @@ namespace anki
 		}                                                                      \
 		}                                                                      \
 	} while(0)
 	} while(0)
 
 
+/// Debug initialize a vulkan structure
+#if ANKI_DEBUG
+#define ANKI_VK_MEMSET_DBG(struct_) memset(&struct_, 0xCC, sizeof(struct_));
+#else
+#define ANKI_VK_MEMSET_DBG(struct_) ((void)0)
+#endif
+
 /// Convert compare op.
 /// Convert compare op.
 VkCompareOp convertCompareOp(CompareOperation ak);
 VkCompareOp convertCompareOp(CompareOperation ak);
 /// @}
 /// @}

+ 19 - 1
include/anki/gr/vulkan/PipelineImpl.h

@@ -10,6 +10,10 @@
 namespace anki
 namespace anki
 {
 {
 
 
+// Forward
+class VertexStateInfo;
+class InputAssemblerStateInfo;
+
 /// @addtogroup vulkan
 /// @addtogroup vulkan
 /// @{
 /// @{
 
 
@@ -17,7 +21,7 @@ namespace anki
 class PipelineImpl : public VulkanObject
 class PipelineImpl : public VulkanObject
 {
 {
 public:
 public:
-	VkPipeline m_ppline = VK_NULL_HANDLE;
+	VkPipeline m_handle = VK_NULL_HANDLE;
 
 
 	PipelineImpl(GrManager* manager)
 	PipelineImpl(GrManager* manager)
 		: VulkanObject(manager)
 		: VulkanObject(manager)
@@ -27,6 +31,20 @@ public:
 	~PipelineImpl();
 	~PipelineImpl();
 
 
 	ANKI_USE_RESULT Error init(const PipelineInitInfo& init);
 	ANKI_USE_RESULT Error init(const PipelineInitInfo& init);
+
+private:
+	ANKI_USE_RESULT Error initGraphics(const PipelineInitInfo& init);
+
+	void initShaders(
+		const PipelineInitInfo& init, VkGraphicsPipelineCreateInfo& ci);
+
+	ANKI_USE_RESULT VkPipelineVertexInputStateCreateInfo* initVertexStage(
+		const VertexStateInfo& vertex,
+		VkPipelineVertexInputStateCreateInfo& ci);
+
+	ANKI_USE_RESULT VkPipelineInputAssemblyStateCreateInfo*
+	initInputAssemblyState(const InputAssemblerStateInfo& ia,
+		VkPipelineInputAssemblyStateCreateInfo& ci);
 };
 };
 /// @}
 /// @}
 
 

+ 4 - 4
include/anki/gr/vulkan/ShaderImpl.h

@@ -19,7 +19,8 @@ namespace anki
 class ShaderImpl : public VulkanObject
 class ShaderImpl : public VulkanObject
 {
 {
 public:
 public:
-	VkShaderModule m_shaderModule = VK_NULL_HANDLE;
+	VkShaderModule m_handle = VK_NULL_HANDLE;
+	ShaderType m_shaderType = ShaderType::COUNT;
 
 
 	ShaderImpl(GrManager* manager)
 	ShaderImpl(GrManager* manager)
 		: VulkanObject(manager)
 		: VulkanObject(manager)
@@ -32,9 +33,8 @@ public:
 
 
 private:
 private:
 	/// Generate SPIRV from GLSL.
 	/// Generate SPIRV from GLSL.
-	ANKI_USE_RESULT Error genSpirv(ShaderType shaderType,
-		const CString& source,
-		std::vector<unsigned int>& spirv);
+	ANKI_USE_RESULT Error genSpirv(
+		const CString& source, std::vector<unsigned int>& spirv);
 };
 };
 /// @}
 /// @}
 
 

+ 178 - 0
src/gr/vulkan/PipelineImpl.cpp

@@ -4,13 +4,191 @@
 // http://www.anki3d.org/LICENSE
 // http://www.anki3d.org/LICENSE
 
 
 #include <anki/gr/vulkan/PipelineImpl.h>
 #include <anki/gr/vulkan/PipelineImpl.h>
+#include <anki/gr/Pipeline.h>
+#include <anki/gr/vulkan/ShaderImpl.h>
 
 
 namespace anki
 namespace anki
 {
 {
 
 
+//==============================================================================
+// Misc                                                                        =
+//==============================================================================
+
+/// Pre-filled VkGraphicsPipelineCreateInfo
+class FilledGraphicsPipelineCreateInfo : public VkGraphicsPipelineCreateInfo
+{
+public:
+	Array<VkPipelineShaderStageCreateInfo, U(ShaderType::COUNT) - 1> m_stages;
+	VkPipelineVertexInputStateCreateInfo m_vertex;
+	Array<VkVertexInputBindingDescription, MAX_VERTEX_ATTRIBUTES> m_bindings;
+	Array<VkVertexInputAttributeDescription, MAX_VERTEX_ATTRIBUTES> m_attribs;
+	VkPipelineInputAssemblyStateCreateInfo m_ia;
+	VkPipelineTessellationStateCreateInfo m_tess;
+	VkPipelineViewportStateCreateInfo m_vp;
+	VkPipelineRasterizationStateCreateInfo m_rast;
+	VkPipelineMultisampleStateCreateInfo m_ms;
+	VkPipelineDepthStencilStateCreateInfo m_ds;
+	VkPipelineColorBlendStateCreateInfo m_color;
+	VkPipelineDynamicStateCreateInfo m_dyn;
+
+	FilledGraphicsPipelineCreateInfo()
+	{
+		memset(this, 0, sizeof(*this));
+
+		sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
+
+		for(VkPipelineShaderStageCreateInfo& stage : m_stages)
+		{
+			stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+		}
+
+		m_vertex.sType =
+			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
+
+		m_ia.sType =
+			VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+
+		m_tess.sType =
+			VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
+
+		m_vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
+
+		m_rast.sType =
+			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+
+		m_ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
+
+		m_ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
+
+		m_color.sType =
+			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+
+		m_dyn.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
+	}
+};
+
+static const FilledGraphicsPipelineCreateInfo FILLED;
+
+//==============================================================================
+// PipelineImpl                                                                =
+//==============================================================================
+
+//==============================================================================
+Error PipelineImpl::initGraphics(const PipelineInitInfo& init)
+{
+	FilledGraphicsPipelineCreateInfo ci = FILLED;
+
+	ci.pStages = &ci.m_stages[0];
+	initShaders(init, ci);
+
+	ci.pVertexInputState = initVertexStage(init.m_vertex, ci.m_vertex);
+
+	ci.layout = 0; // XXX
+	ci.renderPass = 0; // XXX
+	ci.basePipelineHandle = VK_NULL_HANDLE;
+
+	return ErrorCode::NONE;
+}
+
+//==============================================================================
+void PipelineImpl::initShaders(
+	const PipelineInitInfo& init, VkGraphicsPipelineCreateInfo& ci)
+{
+	ci.stageCount = 0;
+
+	for(ShaderType type = ShaderType::FIRST_GRAPHICS;
+		type <= ShaderType::LAST_GRAPHICS;
+		++type)
+	{
+		if(!init.m_shaders[type].isCreated())
+		{
+			continue;
+		}
+
+		ANKI_ASSERT(
+			init.m_shaders[type]->getImplementation().m_shaderType == type);
+		ANKI_ASSERT(init.m_shaders[type]->getImplementation().m_handle);
+
+		VkPipelineShaderStageCreateInfo& stage =
+			const_cast<VkPipelineShaderStageCreateInfo&>(
+				ci.pStages[ci.stageCount]);
+		ANKI_VK_MEMSET_DBG(stage);
+		stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+		stage.pNext = nullptr;
+		stage.flags = 0;
+		stage.stage = VkShaderStageFlagBits(1u << U(type));
+		stage.module = init.m_shaders[type]->getImplementation().m_handle;
+		stage.pName = "main";
+		stage.pSpecializationInfo = nullptr;
+
+		++ci.stageCount;
+	}
+}
+
+//==============================================================================
+VkPipelineVertexInputStateCreateInfo* PipelineImpl::initVertexStage(
+	const VertexStateInfo& vertex, VkPipelineVertexInputStateCreateInfo& ci)
+{
+	if(vertex.m_bindingCount == 0 && vertex.m_attributeCount == 0)
+	{
+		// Early out
+		return nullptr;
+	}
+
+	// First the bindings
+	ci.vertexBindingDescriptionCount = vertex.m_bindingCount;
+	for(U i = 0; i < ci.vertexBindingDescriptionCount; ++i)
+	{
+		VkVertexInputBindingDescription& vkBinding =
+			const_cast<VkVertexInputBindingDescription&>(
+				ci.pVertexBindingDescriptions[i]);
+
+		vkBinding.binding = i;
+		vkBinding.stride = vertex.m_bindings[i].m_stride;
+
+		switch(vertex.m_bindings[i].m_stepRate)
+		{
+		case VertexStepRate::VERTEX:
+			vkBinding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
+			break;
+		case VertexStepRate::INSTANCE:
+			vkBinding.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
+			break;
+		default:
+			ANKI_ASSERT(0);
+		}
+	}
+
+	// Then the attributes
+	ci.vertexAttributeDescriptionCount = vertex.m_attributeCount;
+	for(U i = 0; i < ci.vertexAttributeDescriptionCount; ++i)
+	{
+		VkVertexInputAttributeDescription& vkAttrib =
+			const_cast<VkVertexInputAttributeDescription&>(
+				ci.pVertexAttributeDescriptions[i]);
+
+		vkAttrib.location = 0;
+		vkAttrib.binding = vertex.m_attributes[i].m_binding;
+		vkAttrib.format = VkFormat(0); // XXX
+		vkAttrib.offset = vertex.m_attributes[i].m_offset;
+	}
+
+	return &ci;
+}
+
+//==============================================================================
+VkPipelineInputAssemblyStateCreateInfo*
+PipelineImpl::initInputAssemblyState(const InputAssemblerStateInfo& ia,
+	VkPipelineInputAssemblyStateCreateInfo& ci)
+{
+	// TODO
+	return &ci;
+}
+
 //==============================================================================
 //==============================================================================
 Error PipelineImpl::init(const PipelineInitInfo& init)
 Error PipelineImpl::init(const PipelineInitInfo& init)
 {
 {
+
 	return ErrorCode::NONE;
 	return ErrorCode::NONE;
 }
 }
 
 

+ 8 - 10
src/gr/vulkan/ShaderImpl.cpp

@@ -153,11 +153,10 @@ static const TBuiltInResource GLSLANG_LIMITS = setLimits();
 //==============================================================================
 //==============================================================================
 
 
 //==============================================================================
 //==============================================================================
-Error ShaderImpl::genSpirv(ShaderType shaderType,
-	const CString& source,
-	std::vector<unsigned int>& spirv)
+Error ShaderImpl::genSpirv(
+	const CString& source, std::vector<unsigned int>& spirv)
 {
 {
-	const EShLanguage stage = ankiToGlslangShaderType(shaderType);
+	const EShLanguage stage = ankiToGlslangShaderType(m_shaderType);
 	const EShMessages messages =
 	const EShMessages messages =
 		static_cast<EShMessages>(EShMsgSpvRules | EShMsgVulkanRules);
 		static_cast<EShMessages>(EShMsgSpvRules | EShMsgVulkanRules);
 
 
@@ -191,7 +190,8 @@ Error ShaderImpl::genSpirv(ShaderType shaderType,
 Error ShaderImpl::init(ShaderType shaderType, const CString& source)
 Error ShaderImpl::init(ShaderType shaderType, const CString& source)
 {
 {
 	ANKI_ASSERT(source);
 	ANKI_ASSERT(source);
-	ANKI_ASSERT(m_shaderModule);
+	ANKI_ASSERT(m_handle == VK_NULL_HANDLE);
+	m_shaderType = shaderType;
 
 
 	// Setup the shader
 	// Setup the shader
 	auto alloc = getAllocator();
 	auto alloc = getAllocator();
@@ -209,18 +209,16 @@ Error ShaderImpl::init(ShaderType shaderType, const CString& source)
 		&source[0]);
 		&source[0]);
 
 
 	std::vector<unsigned int> spirv;
 	std::vector<unsigned int> spirv;
-	ANKI_CHECK(genSpirv(shaderType, fullSrc.toCString(), spirv));
+	ANKI_CHECK(genSpirv(fullSrc.toCString(), spirv));
 	ANKI_ASSERT(!spirv.empty());
 	ANKI_ASSERT(!spirv.empty());
 
 
-	VkShaderModuleCreateInfo ci = {
-		VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
+	VkShaderModuleCreateInfo ci = {VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
 		nullptr,
 		nullptr,
 		0,
 		0,
 		spirv.size() * sizeof(unsigned int),
 		spirv.size() * sizeof(unsigned int),
 		&spirv[0]};
 		&spirv[0]};
 
 
-	ANKI_VK_CHECK(
-		vkCreateShaderModule(getDevice(), &ci, nullptr, &m_shaderModule));
+	ANKI_VK_CHECK(vkCreateShaderModule(getDevice(), &ci, nullptr, &m_handle));
 
 
 	return ErrorCode::NONE;
 	return ErrorCode::NONE;
 }
 }

+ 0 - 1
src/renderer/Is.cpp

@@ -479,7 +479,6 @@ Error Is::initInternal(const ConfigSet& config)
 Error Is::populateBuffers(RenderingContext& ctx)
 Error Is::populateBuffers(RenderingContext& ctx)
 {
 {
 	ANKI_TRACE_START_EVENT(RENDER_IS);
 	ANKI_TRACE_START_EVENT(RENDER_IS);
-	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
 	ThreadPool& threadPool = m_r->getThreadPool();
 	ThreadPool& threadPool = m_r->getThreadPool();
 	m_frc = ctx.m_frustumComponent;
 	m_frc = ctx.m_frustumComponent;
 	VisibilityTestResults& vi = m_frc->getVisibilityTestResults();
 	VisibilityTestResults& vi = m_frc->getVisibilityTestResults();