Bläddra i källkod

Some more work on the Vulkan pipeline

Panagiotis Christopoulos Charitos 9 år sedan
förälder
incheckning
82e681f5ff

+ 1 - 1
LICENSE

@@ -1,5 +1,5 @@
 AnKi 3D Engine
-Copyright (c) 2009 - 2015 Panagiotis Christopoulos Charitos.
+Copyright (c) 2009 - 2016 Panagiotis Christopoulos Charitos.
 All rights reserved.
 
 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_USE_RESULT __attribute__((warn_unused_result))
 #	define ANKI_FORCE_INLINE __attribute__((always_inline))
+#	define ANKI_UNUSED __attribute__((__unused__))
 #else
 #	define ANKI_LIKELY(x) ((x) == 1)
 #	define ANKI_UNLIKELY(x) ((x) == 1)
 #	define ANKI_RESTRICT
 #	define ANKI_USE_RESULT
 #	define ANKI_FORCE_INLINE
+#	define ANKI_UNUSED
 #endif
 
 #ifdef ANKI_BUILD

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

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

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

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

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

@@ -29,6 +29,13 @@ namespace anki
 		}                                                                      \
 	} 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.
 VkCompareOp convertCompareOp(CompareOperation ak);
 /// @}

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

@@ -10,6 +10,10 @@
 namespace anki
 {
 
+// Forward
+class VertexStateInfo;
+class InputAssemblerStateInfo;
+
 /// @addtogroup vulkan
 /// @{
 
@@ -17,7 +21,7 @@ namespace anki
 class PipelineImpl : public VulkanObject
 {
 public:
-	VkPipeline m_ppline = VK_NULL_HANDLE;
+	VkPipeline m_handle = VK_NULL_HANDLE;
 
 	PipelineImpl(GrManager* manager)
 		: VulkanObject(manager)
@@ -27,6 +31,20 @@ public:
 	~PipelineImpl();
 
 	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
 {
 public:
-	VkShaderModule m_shaderModule = VK_NULL_HANDLE;
+	VkShaderModule m_handle = VK_NULL_HANDLE;
+	ShaderType m_shaderType = ShaderType::COUNT;
 
 	ShaderImpl(GrManager* manager)
 		: VulkanObject(manager)
@@ -32,9 +33,8 @@ public:
 
 private:
 	/// 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
 
 #include <anki/gr/vulkan/PipelineImpl.h>
+#include <anki/gr/Pipeline.h>
+#include <anki/gr/vulkan/ShaderImpl.h>
 
 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)
 {
+
 	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 =
 		static_cast<EShMessages>(EShMsgSpvRules | EShMsgVulkanRules);
 
@@ -191,7 +190,8 @@ Error ShaderImpl::genSpirv(ShaderType shaderType,
 Error ShaderImpl::init(ShaderType shaderType, const CString& source)
 {
 	ANKI_ASSERT(source);
-	ANKI_ASSERT(m_shaderModule);
+	ANKI_ASSERT(m_handle == VK_NULL_HANDLE);
+	m_shaderType = shaderType;
 
 	// Setup the shader
 	auto alloc = getAllocator();
@@ -209,18 +209,16 @@ Error ShaderImpl::init(ShaderType shaderType, const CString& source)
 		&source[0]);
 
 	std::vector<unsigned int> spirv;
-	ANKI_CHECK(genSpirv(shaderType, fullSrc.toCString(), spirv));
+	ANKI_CHECK(genSpirv(fullSrc.toCString(), spirv));
 	ANKI_ASSERT(!spirv.empty());
 
-	VkShaderModuleCreateInfo ci = {
-		VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
+	VkShaderModuleCreateInfo ci = {VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
 		nullptr,
 		0,
 		spirv.size() * sizeof(unsigned int),
 		&spirv[0]};
 
-	ANKI_VK_CHECK(
-		vkCreateShaderModule(getDevice(), &ci, nullptr, &m_shaderModule));
+	ANKI_VK_CHECK(vkCreateShaderModule(getDevice(), &ci, nullptr, &m_handle));
 
 	return ErrorCode::NONE;
 }

+ 0 - 1
src/renderer/Is.cpp

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