tests: Add test for creating mesh-only shader
Change-Id: I658d91ed5a61933921ed601672239e1ee94ffb81
diff --git a/tests/vkpositivelayertests.cpp b/tests/vkpositivelayertests.cpp
index 8390741..27cec81 100644
--- a/tests/vkpositivelayertests.cpp
+++ b/tests/vkpositivelayertests.cpp
@@ -12276,3 +12276,83 @@
ASSERT_NO_FATAL_FAILURE(vk::DestroyInstance(instance, nullptr));
}
+
+TEST_F(VkPositiveLayerTest, MeshShaderOnly) {
+ TEST_DESCRIPTION("Test using a mesh shader without a vertex shader.");
+
+ 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());
+ std::array<const char *, 2> required_device_extensions = {
+ {VK_NV_MESH_SHADER_EXTENSION_NAME, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_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;
+ }
+ }
+
+ if (IsPlatform(kMockICD) || DeviceSimulation()) {
+ printf("%sNot suppored by MockICD, skipping tests\n", kSkipPrefix);
+ return;
+ }
+
+ PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
+ (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
+ ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
+
+ // Create a device that enables mesh_shader
+ auto mesh_shader_features = LvlInitStruct<VkPhysicalDeviceMeshShaderFeaturesNV>();
+ auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&mesh_shader_features);
+ vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
+
+ ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
+ if (mesh_shader_features.meshShader != VK_TRUE) {
+ printf("%sMesh shader feature not supported\n", kSkipPrefix);
+ return;
+ }
+
+ ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+ static const char meshShaderText[] = R"glsl(
+ #version 450
+ #extension GL_NV_mesh_shader : require
+ layout(local_size_x = 1) in;
+ layout(max_vertices = 3) out;
+ layout(max_primitives = 1) out;
+ layout(triangles) out;
+ void main() {
+ gl_MeshVerticesNV[0].gl_Position = vec4(-1.0, -1.0, 0, 1);
+ gl_MeshVerticesNV[1].gl_Position = vec4( 1.0, -1.0, 0, 1);
+ gl_MeshVerticesNV[2].gl_Position = vec4( 0.0, 1.0, 0, 1);
+ gl_PrimitiveIndicesNV[0] = 0;
+ gl_PrimitiveIndicesNV[1] = 1;
+ gl_PrimitiveIndicesNV[2] = 2;
+ gl_PrimitiveCountNV = 1;
+ }
+ )glsl";
+
+ VkShaderObj ms(m_device, meshShaderText, VK_SHADER_STAGE_MESH_BIT_NV, this);
+ VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+ CreatePipelineHelper helper(*this);
+ helper.InitInfo();
+ helper.shader_stages_ = {ms.GetStageCreateInfo(), fs.GetStageCreateInfo()};
+
+ // Ensure pVertexInputState and pInputAssembly state are null, as these should be ignored.
+ helper.gp_ci_.pVertexInputState = nullptr;
+ helper.gp_ci_.pInputAssemblyState = nullptr;
+
+ helper.InitState();
+
+ m_errorMonitor->ExpectSuccess();
+ helper.CreateGraphicsPipeline();
+ m_errorMonitor->VerifyNotFound();
+}