aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Bolz <jbolz@nvidia.com>2019-08-16 16:29:53 -0500
committerMark Lobodzinski <mark@lunarg.com>2019-08-20 08:34:31 -0600
commitf390c6c1fffde2eb1a6c3bf9519327064bce355a (patch)
treed6e4ff6a25c0f39ba655ba3fa096e3326b6114f8
parent8125a8b42a9e82cbcbccb70b6389ce90dbc12f25 (diff)
downloadvulkan-validation-layers-f390c6c1fffde2eb1a6c3bf9519327064bce355a.tar.gz
tests: Add tests for VK_EXT_line_rasterization
-rw-r--r--tests/layer_validation_tests.cpp28
-rw-r--r--tests/layer_validation_tests.h21
-rw-r--r--tests/vklayertests_command.cpp43
-rw-r--r--tests/vklayertests_pipeline_shader.cpp104
-rw-r--r--tests/vkrenderframework.cpp16
-rw-r--r--tests/vkrenderframework.h2
6 files changed, 203 insertions, 11 deletions
diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp
index 19572ffaf..f87ffa46a 100644
--- a/tests/layer_validation_tests.cpp
+++ b/tests/layer_validation_tests.cpp
@@ -796,6 +796,22 @@ void VkLayerTest::VKTriangleTest(BsoFailSelect failCase) {
pipelineobj.SetInputAssembly(&ia_state);
break;
}
+ case BsoFailLineStipple: {
+ pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_LINE_STIPPLE_EXT);
+ VkPipelineInputAssemblyStateCreateInfo ia_state = {};
+ ia_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+ ia_state.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
+ pipelineobj.SetInputAssembly(&ia_state);
+
+ VkPipelineRasterizationLineStateCreateInfoEXT line_state = {};
+ line_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT;
+ line_state.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT;
+ line_state.stippledLineEnable = VK_TRUE;
+ line_state.lineStippleFactor = 0;
+ line_state.lineStipplePattern = 0;
+ pipelineobj.SetLineState(&line_state);
+ break;
+ }
case BsoFailDepthBias: {
pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_DEPTH_BIAS);
VkPipelineRasterizationStateCreateInfo rs_state = {};
@@ -1460,7 +1476,7 @@ void CreatePipelineHelper::InitShaderInfo() {
void CreatePipelineHelper::InitRasterizationInfo() {
rs_state_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
- rs_state_ci_.pNext = nullptr;
+ rs_state_ci_.pNext = &line_state_ci_;
rs_state_ci_.flags = 0;
rs_state_ci_.depthClampEnable = VK_FALSE;
rs_state_ci_.rasterizerDiscardEnable = VK_FALSE;
@@ -1471,6 +1487,15 @@ void CreatePipelineHelper::InitRasterizationInfo() {
rs_state_ci_.lineWidth = 1.0F;
}
+void CreatePipelineHelper::InitLineRasterizationInfo() {
+ line_state_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT;
+ line_state_ci_.pNext = nullptr;
+ line_state_ci_.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
+ line_state_ci_.stippledLineEnable = VK_FALSE;
+ line_state_ci_.lineStippleFactor = 0;
+ line_state_ci_.lineStipplePattern = 0;
+}
+
void CreatePipelineHelper::InitBlendStateInfo() {
cb_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
cb_ci_.logicOpEnable = VK_FALSE;
@@ -1531,6 +1556,7 @@ void CreatePipelineHelper::InitInfo() {
InitDynamicStateInfo();
InitShaderInfo();
InitRasterizationInfo();
+ InitLineRasterizationInfo();
InitBlendStateInfo();
InitGraphicsPipelineInfo();
InitPipelineCacheInfo();
diff --git a/tests/layer_validation_tests.h b/tests/layer_validation_tests.h
index 195bfff01..5ef980370 100644
--- a/tests/layer_validation_tests.h
+++ b/tests/layer_validation_tests.h
@@ -80,7 +80,8 @@ enum BsoFailSelect {
BsoFailIndexBufferBadSize,
BsoFailIndexBufferBadOffset,
BsoFailIndexBufferBadMapSize,
- BsoFailIndexBufferBadMapOffset
+ BsoFailIndexBufferBadMapOffset,
+ BsoFailLineStipple,
};
static const char bindStateMinimalShaderText[] = "#version 450\nvoid main() {}\n";
@@ -437,6 +438,7 @@ struct CreatePipelineHelper {
VkPipelineLayoutObj pipeline_layout_;
VkPipelineDynamicStateCreateInfo dyn_state_ci_ = {};
VkPipelineRasterizationStateCreateInfo rs_state_ci_ = {};
+ VkPipelineRasterizationLineStateCreateInfoEXT line_state_ci_ = {};
VkPipelineColorBlendAttachmentState cb_attachments_ = {};
VkPipelineColorBlendStateCreateInfo cb_ci_ = {};
VkGraphicsPipelineCreateInfo gp_ci_ = {};
@@ -457,6 +459,7 @@ struct CreatePipelineHelper {
void InitDynamicStateInfo();
void InitShaderInfo();
void InitRasterizationInfo();
+ void InitLineRasterizationInfo();
void InitBlendStateInfo();
void InitGraphicsPipelineInfo();
void InitPipelineCacheInfo();
@@ -475,7 +478,7 @@ struct CreatePipelineHelper {
// info_override can be any callable that takes a CreatePipelineHeper &
// flags, error can be any args accepted by "SetDesiredFailure".
template <typename Test, typename OverrideFunc, typename Error>
- static void OneshotTest(Test &test, OverrideFunc &info_override, const VkFlags flags, const std::vector<Error> &errors,
+ static void OneshotTest(Test &test, const OverrideFunc &info_override, const VkFlags flags, const std::vector<Error> &errors,
bool positive_test = false) {
CreatePipelineHelper helper(test);
helper.InitInfo();
@@ -493,7 +496,8 @@ struct CreatePipelineHelper {
}
template <typename Test, typename OverrideFunc, typename Error>
- static void OneshotTest(Test &test, OverrideFunc &info_override, const VkFlags flags, Error error, bool positive_test = false) {
+ static void OneshotTest(Test &test, const OverrideFunc &info_override, const VkFlags flags, Error error,
+ bool positive_test = false) {
OneshotTest(test, info_override, flags, std::vector<Error>(1, error), positive_test);
}
};
@@ -530,7 +534,7 @@ struct CreateComputePipelineHelper {
// info_override can be any callable that takes a CreatePipelineHeper &
// flags, error can be any args accepted by "SetDesiredFailure".
template <typename Test, typename OverrideFunc, typename Error>
- static void OneshotTest(Test &test, OverrideFunc &info_override, const VkFlags flags, const std::vector<Error> &errors,
+ static void OneshotTest(Test &test, const OverrideFunc &info_override, const VkFlags flags, const std::vector<Error> &errors,
bool positive_test = false) {
CreateComputePipelineHelper helper(test);
helper.InitInfo();
@@ -548,7 +552,8 @@ struct CreateComputePipelineHelper {
}
template <typename Test, typename OverrideFunc, typename Error>
- static void OneshotTest(Test &test, OverrideFunc &info_override, const VkFlags flags, Error error, bool positive_test = false) {
+ static void OneshotTest(Test &test, const OverrideFunc &info_override, const VkFlags flags, Error error,
+ bool positive_test = false) {
OneshotTest(test, info_override, flags, std::vector<Error>(1, error), positive_test);
}
};
@@ -594,7 +599,7 @@ struct CreateNVRayTracingPipelineHelper {
// info_override can be any callable that takes a CreateNVRayTracingPipelineHelper &
// flags, error can be any args accepted by "SetDesiredFailure".
template <typename Test, typename OverrideFunc, typename Error>
- static void OneshotTest(Test &test, OverrideFunc &info_override, const std::vector<Error> &errors,
+ static void OneshotTest(Test &test, const OverrideFunc &info_override, const std::vector<Error> &errors,
const VkFlags flags = VK_DEBUG_REPORT_ERROR_BIT_EXT) {
CreateNVRayTracingPipelineHelper helper(test);
helper.InitInfo();
@@ -607,13 +612,13 @@ struct CreateNVRayTracingPipelineHelper {
}
template <typename Test, typename OverrideFunc, typename Error>
- static void OneshotTest(Test &test, OverrideFunc &info_override, Error error,
+ static void OneshotTest(Test &test, const OverrideFunc &info_override, Error error,
const VkFlags flags = VK_DEBUG_REPORT_ERROR_BIT_EXT) {
OneshotTest(test, info_override, std::vector<Error>(1, error), flags);
}
template <typename Test, typename OverrideFunc>
- static void OneshotPositiveTest(Test &test, OverrideFunc &info_override,
+ static void OneshotPositiveTest(Test &test, const OverrideFunc &info_override,
const VkDebugReportFlagsEXT message_flag_mask = VK_DEBUG_REPORT_ERROR_BIT_EXT) {
CreateNVRayTracingPipelineHelper helper(test);
helper.InitInfo();
diff --git a/tests/vklayertests_command.cpp b/tests/vklayertests_command.cpp
index ef852e7d9..3724cc878 100644
--- a/tests/vklayertests_command.cpp
+++ b/tests/vklayertests_command.cpp
@@ -179,6 +179,49 @@ TEST_F(VkLayerTest, DynamicLineWidthNotBound) {
m_errorMonitor->VerifyFound();
}
+TEST_F(VkLayerTest, DynamicLineStippleNotBound) {
+ TEST_DESCRIPTION(
+ "Run a simple draw calls to validate failure when Line Stipple dynamic state is required but not correctly bound.");
+
+ if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
+ m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
+ } else {
+ printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
+ VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
+ return;
+ }
+ ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
+ std::array<const char *, 1> required_device_extensions = {{VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME}};
+ for (auto device_extension : required_device_extensions) {
+ if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
+ m_device_extension_names.push_back(device_extension);
+ } else {
+ printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
+ return;
+ }
+ }
+
+ PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
+ (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
+ ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
+
+ auto line_rasterization_features = lvl_init_struct<VkPhysicalDeviceLineRasterizationFeaturesEXT>();
+ auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&line_rasterization_features);
+ vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
+
+ if (!line_rasterization_features.stippledBresenhamLines || !line_rasterization_features.bresenhamLines) {
+ printf("%sStipple Bresenham lines not supported; skipped.\n", kSkipPrefix);
+ return;
+ }
+
+ ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
+
+ m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+ "Dynamic line stipple state not set for this command buffer");
+ VKTriangleTest(BsoFailLineStipple);
+ m_errorMonitor->VerifyFound();
+}
+
TEST_F(VkLayerTest, DynamicViewportNotBound) {
TEST_DESCRIPTION(
"Run a simple draw calls to validate failure when Viewport dynamic state is required but not correctly bound.");
diff --git a/tests/vklayertests_pipeline_shader.cpp b/tests/vklayertests_pipeline_shader.cpp
index 2ca5dab21..e928ddd04 100644
--- a/tests/vklayertests_pipeline_shader.cpp
+++ b/tests/vklayertests_pipeline_shader.cpp
@@ -5596,3 +5596,107 @@ TEST_F(VkLayerTest, CreatePipelineCheckDemoteToHelperInvocation) {
pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle());
m_errorMonitor->VerifyFound();
}
+
+TEST_F(VkLayerTest, CreatePipelineCheckLineRasterization) {
+ TEST_DESCRIPTION("Test VK_EXT_line_rasterization state against feature enables.");
+
+ if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
+ m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
+ } else {
+ printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
+ VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
+ return;
+ }
+ ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
+ std::array<const char *, 1> required_device_extensions = {{VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME}};
+ for (auto device_extension : required_device_extensions) {
+ if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
+ m_device_extension_names.push_back(device_extension);
+ } else {
+ printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
+ return;
+ }
+ }
+
+ PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
+ (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
+ ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
+
+ auto line_rasterization_features = lvl_init_struct<VkPhysicalDeviceLineRasterizationFeaturesEXT>();
+ auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&line_rasterization_features);
+ vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
+
+ line_rasterization_features.rectangularLines = VK_FALSE;
+ line_rasterization_features.bresenhamLines = VK_FALSE;
+ line_rasterization_features.smoothLines = VK_FALSE;
+ line_rasterization_features.stippledRectangularLines = VK_FALSE;
+ line_rasterization_features.stippledBresenhamLines = VK_FALSE;
+ line_rasterization_features.stippledSmoothLines = VK_FALSE;
+
+ ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
+ ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+ CreatePipelineHelper::OneshotTest(
+ *this,
+ [&](CreatePipelineHelper &helper) {
+ helper.line_state_ci_.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT;
+ helper.pipe_ms_state_ci_.alphaToCoverageEnable = VK_TRUE;
+ },
+ VK_DEBUG_REPORT_ERROR_BIT_EXT,
+ std::vector<const char *>{"VUID-VkGraphicsPipelineCreateInfo-lineRasterizationMode-02766",
+ "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-lineRasterizationMode-02769"});
+
+ CreatePipelineHelper::OneshotTest(
+ *this,
+ [&](CreatePipelineHelper &helper) {
+ helper.line_state_ci_.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT;
+ helper.line_state_ci_.stippledLineEnable = VK_TRUE;
+ },
+ VK_DEBUG_REPORT_ERROR_BIT_EXT,
+ std::vector<const char *>{"VUID-VkGraphicsPipelineCreateInfo-stippledLineEnable-02767",
+ "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-lineRasterizationMode-02769",
+ "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02772"});
+
+ CreatePipelineHelper::OneshotTest(
+ *this,
+ [&](CreatePipelineHelper &helper) {
+ helper.line_state_ci_.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
+ helper.line_state_ci_.stippledLineEnable = VK_TRUE;
+ },
+ VK_DEBUG_REPORT_ERROR_BIT_EXT,
+ std::vector<const char *>{"VUID-VkGraphicsPipelineCreateInfo-stippledLineEnable-02767",
+ "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-lineRasterizationMode-02768",
+ "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02771"});
+
+ CreatePipelineHelper::OneshotTest(
+ *this,
+ [&](CreatePipelineHelper &helper) {
+ helper.line_state_ci_.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT;
+ helper.line_state_ci_.stippledLineEnable = VK_TRUE;
+ },
+ VK_DEBUG_REPORT_ERROR_BIT_EXT,
+ std::vector<const char *>{"VUID-VkGraphicsPipelineCreateInfo-stippledLineEnable-02767",
+ "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-lineRasterizationMode-02770",
+ "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02773"});
+
+ CreatePipelineHelper::OneshotTest(
+ *this,
+ [&](CreatePipelineHelper &helper) {
+ helper.line_state_ci_.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
+ helper.line_state_ci_.stippledLineEnable = VK_TRUE;
+ },
+ VK_DEBUG_REPORT_ERROR_BIT_EXT,
+ std::vector<const char *>{"VUID-VkGraphicsPipelineCreateInfo-stippledLineEnable-02767",
+ "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02774"});
+
+ PFN_vkCmdSetLineStippleEXT vkCmdSetLineStippleEXT =
+ (PFN_vkCmdSetLineStippleEXT)vkGetDeviceProcAddr(m_device->device(), "vkCmdSetLineStippleEXT");
+ ASSERT_TRUE(vkCmdSetLineStippleEXT != nullptr);
+
+ m_commandBuffer->begin();
+ m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetLineStippleEXT-lineStippleFactor-02776");
+ vkCmdSetLineStippleEXT(m_commandBuffer->handle(), 0, 0);
+ m_errorMonitor->VerifyFound();
+ vkCmdSetLineStippleEXT(m_commandBuffer->handle(), 1, 1);
+ m_errorMonitor->VerifyFound();
+}
diff --git a/tests/vkrenderframework.cpp b/tests/vkrenderframework.cpp
index 08e6fa619..f0008355f 100644
--- a/tests/vkrenderframework.cpp
+++ b/tests/vkrenderframework.cpp
@@ -1610,7 +1610,7 @@ VkPipelineObj::VkPipelineObj(VkDeviceObj *device) {
m_vp_state.pScissors = nullptr;
m_rs_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
- m_rs_state.pNext = nullptr;
+ m_rs_state.pNext = &m_line_state;
m_rs_state.flags = 0;
m_rs_state.depthClampEnable = VK_FALSE;
m_rs_state.rasterizerDiscardEnable = VK_FALSE;
@@ -1623,6 +1623,13 @@ VkPipelineObj::VkPipelineObj(VkDeviceObj *device) {
m_rs_state.depthBiasSlopeFactor = 0.0f;
m_rs_state.lineWidth = 1.0f;
+ m_line_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT;
+ m_line_state.pNext = nullptr;
+ m_line_state.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
+ m_line_state.stippledLineEnable = VK_FALSE;
+ m_line_state.lineStippleFactor = 0;
+ m_line_state.lineStipplePattern = 0;
+
m_ms_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
m_ms_state.pNext = nullptr;
m_ms_state.flags = 0;
@@ -1698,10 +1705,15 @@ void VkPipelineObj::SetMSAA(const VkPipelineMultisampleStateCreateInfo *ms_state
void VkPipelineObj::SetInputAssembly(const VkPipelineInputAssemblyStateCreateInfo *ia_state) { m_ia_state = *ia_state; }
-void VkPipelineObj::SetRasterization(const VkPipelineRasterizationStateCreateInfo *rs_state) { m_rs_state = *rs_state; }
+void VkPipelineObj::SetRasterization(const VkPipelineRasterizationStateCreateInfo *rs_state) {
+ m_rs_state = *rs_state;
+ m_rs_state.pNext = &m_line_state;
+}
void VkPipelineObj::SetTessellation(const VkPipelineTessellationStateCreateInfo *te_state) { m_te_state = te_state; }
+void VkPipelineObj::SetLineState(const VkPipelineRasterizationLineStateCreateInfoEXT *line_state) { m_line_state = *line_state; }
+
void VkPipelineObj::InitGraphicsPipelineCreateInfo(VkGraphicsPipelineCreateInfo *gp_ci) {
gp_ci->stageCount = m_shaderStages.size();
gp_ci->pStages = m_shaderStages.size() ? m_shaderStages.data() : nullptr;
diff --git a/tests/vkrenderframework.h b/tests/vkrenderframework.h
index 2b8561d4f..f6e8d33b6 100644
--- a/tests/vkrenderframework.h
+++ b/tests/vkrenderframework.h
@@ -452,6 +452,7 @@ class VkPipelineObj : public vk_testing::Pipeline {
void SetTessellation(const VkPipelineTessellationStateCreateInfo *te_state);
void SetViewport(const vector<VkViewport> viewports);
void SetScissor(const vector<VkRect2D> scissors);
+ void SetLineState(const VkPipelineRasterizationLineStateCreateInfoEXT *line_state);
void InitGraphicsPipelineCreateInfo(VkGraphicsPipelineCreateInfo *gp_ci);
@@ -467,6 +468,7 @@ class VkPipelineObj : public vk_testing::Pipeline {
VkPipelineMultisampleStateCreateInfo m_ms_state;
VkPipelineTessellationStateCreateInfo const *m_te_state;
VkPipelineDynamicStateCreateInfo m_pd_state;
+ VkPipelineRasterizationLineStateCreateInfoEXT m_line_state;
vector<VkDynamicState> m_dynamic_state_enables;
vector<VkViewport> m_viewports;
vector<VkRect2D> m_scissors;