From 4a27ab1974070eba47f940a96d102216ca4a34c2 Mon Sep 17 00:00:00 2001
From: Tobias Frisch <tfrisch@uni-koblenz.de>
Date: Tue, 25 Jan 2022 16:43:09 +0100
Subject: [PATCH] Added support for tessellation shader stages

Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de>
---
 include/vkcv/GraphicsPipelineConfig.hpp |  1 +
 src/vkcv/GraphicsPipelineManager.cpp    | 57 ++++++++++++++++++++++++-
 2 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/include/vkcv/GraphicsPipelineConfig.hpp b/include/vkcv/GraphicsPipelineConfig.hpp
index 6d466c4a..be3ba8ef 100644
--- a/include/vkcv/GraphicsPipelineConfig.hpp
+++ b/include/vkcv/GraphicsPipelineConfig.hpp
@@ -39,6 +39,7 @@ namespace vkcv {
         DepthTest                               m_depthTest                     = DepthTest::LessEqual;
         bool                                    m_depthWrite                    = true;
         bool                                    m_alphaToCoverage               = false;
+		uint32_t								m_tessellationControlPoints		= 0;
     };
 
 }
\ No newline at end of file
diff --git a/src/vkcv/GraphicsPipelineManager.cpp b/src/vkcv/GraphicsPipelineManager.cpp
index a461051f..8a12ba65 100644
--- a/src/vkcv/GraphicsPipelineManager.cpp
+++ b/src/vkcv/GraphicsPipelineManager.cpp
@@ -195,6 +195,15 @@ namespace vkcv
 		return pipelineInputAssemblyStateCreateInfo;
 	}
 	
+	vk::PipelineTessellationStateCreateInfo createPipelineTessellationStateCreateInfo(const GraphicsPipelineConfig &config) {
+		vk::PipelineTessellationStateCreateInfo pipelineTessellationStateCreateInfo(
+				{},
+				config.m_tessellationControlPoints
+		);
+		
+		return pipelineTessellationStateCreateInfo;
+	}
+	
 	/**
 	 * Creates a Pipeline Viewport State Create Info Struct with default set viewport and scissor settings.
 	 * @param config provides with and height of the output window
@@ -424,7 +433,13 @@ namespace vkcv
         const bool existsVertexShader   = config.m_ShaderProgram.existsShader(ShaderStage::VERTEX);
         const bool existsFragmentShader = config.m_ShaderProgram.existsShader(ShaderStage::FRAGMENT);
         const bool existsGeometryShader = config.m_ShaderProgram.existsShader(ShaderStage::GEOMETRY);
-        const bool validGeometryStages  = existsVertexShader || (existsTaskShader && existsMeshShader);
+		const bool existsTessellationControlShader = config.m_ShaderProgram.existsShader(ShaderStage::TESS_CONTROL);
+		const bool existsTessellationEvaluationShader = config.m_ShaderProgram.existsShader(ShaderStage::TESS_EVAL);
+		
+        const bool validGeometryStages  = (
+				(existsVertexShader && (existsTessellationControlShader == existsTessellationEvaluationShader)) ||
+				(existsTaskShader && existsMeshShader)
+		);
 
         if (!validGeometryStages)
         {
@@ -529,6 +544,40 @@ namespace vkcv
                 return GraphicsPipelineHandle();
             }
         }
+	
+		if (existsTessellationControlShader) {
+			vk::PipelineShaderStageCreateInfo createInfo;
+			const bool success = createPipelineShaderStageCreateInfo(
+					config.m_ShaderProgram,
+					ShaderStage::TESS_CONTROL,
+					m_Device,
+					&createInfo);
+		
+			if (success) {
+				shaderStages.push_back(createInfo);
+			}
+			else {
+				destroyShaderModules();
+				return GraphicsPipelineHandle();
+			}
+		}
+	
+		if (existsTessellationEvaluationShader) {
+			vk::PipelineShaderStageCreateInfo createInfo;
+			const bool success = createPipelineShaderStageCreateInfo(
+					config.m_ShaderProgram,
+					ShaderStage::TESS_EVAL,
+					m_Device,
+					&createInfo);
+		
+			if (success) {
+				shaderStages.push_back(createInfo);
+			}
+			else {
+				destroyShaderModules();
+				return GraphicsPipelineHandle();
+			}
+		}
 
         // vertex input state
         // Fill up VertexInputBindingDescription and VertexInputAttributeDescription Containers
@@ -545,6 +594,10 @@ namespace vkcv
         vk::PipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo =
                 createPipelineInputAssemblyStateCreateInfo(config);
 
+		// tesselation state
+		vk::PipelineTessellationStateCreateInfo pipelineTessellationStateCreateInfo =
+				createPipelineTessellationStateCreateInfo(config);
+		
         // viewport state
         vk::PipelineViewportStateCreateInfo pipelineViewportStateCreateInfo =
                 createPipelineViewportStateCreateInfo(config);
@@ -601,7 +654,7 @@ namespace vkcv
                 shaderStages.data(),
                 &pipelineVertexInputStateCreateInfo,
                 &pipelineInputAssemblyStateCreateInfo,
-                nullptr,
+                &pipelineTessellationStateCreateInfo,
                 &pipelineViewportStateCreateInfo,
                 &pipelineRasterizationStateCreateInfo,
                 &pipelineMultisampleStateCreateInfo,
-- 
GitLab