| /* |
| * Copyright (c) 2023-2024 Nintendo |
| * Copyright (c) 2023-2024 LunarG, Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| */ |
| |
| #include "../framework/layer_validation_tests.h" |
| #include "../framework/descriptor_helper.h" |
| #include "../framework/render_pass_helper.h" |
| |
| TEST_F(NegativeShaderObject, SpirvCodeSize) { |
| TEST_DESCRIPTION("Create shader with invalid spirv code size."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-codeSize-08735"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]) - 2u; |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, LinkedComputeShader) { |
| TEST_DESCRIPTION("Create compute shader with linked flag."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-flags-08412"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, kMinimalShaderGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidFlags) { |
| TEST_DESCRIPTION("Create shader with invalid flags."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.flags = VK_SHADER_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT; |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-flags-08992"); |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-flags-08485"); |
| createInfo.flags = VK_SHADER_CREATE_DISPATCH_BASE_BIT_EXT; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-flags-08486"); |
| createInfo.flags = VK_SHADER_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_EXT; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-flags-08488"); |
| createInfo.flags = VK_SHADER_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidMeshShaderExtFlags) { |
| TEST_DESCRIPTION("Create mesh shader with invalid flags."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-flags-08414"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_1, true, false)); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.flags = VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT; |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, VertexNextStage) { |
| TEST_DESCRIPTION("Create vertex shader with invalid next stage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-nextStage-08427"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.nextStage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, TessellationControlNextStage) { |
| TEST_DESCRIPTION("Create tessellation control shader with invalid next stage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-nextStage-08430"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, kTessellationControlMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; |
| createInfo.nextStage = VK_SHADER_STAGE_GEOMETRY_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, TessellationEvaluationNextStage) { |
| TEST_DESCRIPTION("Create tessellation evaluation shader with invalid next stage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-nextStage-08431"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, kTessellationEvalMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| createInfo.nextStage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, GeometryNextStage) { |
| TEST_DESCRIPTION("Create geometry shader with invalid next stage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-nextStage-08433"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_GEOMETRY_BIT, kGeometryMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_GEOMETRY_BIT; |
| createInfo.nextStage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, FragmentNextStage) { |
| TEST_DESCRIPTION("Create fragment shader with invalid next stage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-nextStage-08434"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfo.nextStage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, TaskNextStage) { |
| TEST_DESCRIPTION("Create task shader with invalid next stage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-nextStage-08435"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_2, true, false)); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_TASK_BIT_EXT, kTaskMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_TASK_BIT_EXT; |
| createInfo.nextStage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MeshNextStage) { |
| TEST_DESCRIPTION("Create mesh shader with invalid next stage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-nextStage-08436"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_2, false, true)); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| createInfo.nextStage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, TaskNVNextStage) { |
| TEST_DESCRIPTION("Create task shader with invalid next stage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-nextStage-08435"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_2, true, false)); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_TASK_BIT_NV, kTaskMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_TASK_BIT_NV; |
| createInfo.nextStage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MeshNVNextStage) { |
| TEST_DESCRIPTION("Create mesh shader with invalid next stage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-nextStage-08436"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_NV_MESH_SHADER_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitFramework()); |
| VkPhysicalDeviceMeshShaderFeaturesNV mesh_shader_features_nv = vku::InitStructHelper(); |
| VkPhysicalDeviceDynamicRenderingFeatures dynamic_rendering_features = vku::InitStructHelper(&mesh_shader_features_nv); |
| VkPhysicalDeviceShaderObjectFeaturesEXT shader_object_features = vku::InitStructHelper(&dynamic_rendering_features); |
| auto features2 = GetPhysicalDeviceFeatures2(shader_object_features); |
| RETURN_IF_SKIP(InitState(nullptr, &features2)); |
| if (mesh_shader_features_nv.meshShader == VK_FALSE) { |
| GTEST_SKIP() << "shadingRateImage not supported."; |
| } |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_NV, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_MESH_BIT_NV; |
| createInfo.nextStage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, BinaryCodeAlignment) { |
| TEST_DESCRIPTION("Create binary shader with invalid binary code alignment."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-pCode-08492"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| std::vector<uint32_t> spv(256); |
| |
| auto ptr = reinterpret_cast<std::uintptr_t>(spv.data()) + sizeof(uint8_t); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_BINARY_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = reinterpret_cast<void*>(ptr); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, SpirvCodeAlignment) { |
| TEST_DESCRIPTION("Create shader with invalid binary code alignment."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-pCode-08493"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| auto ptr = reinterpret_cast<std::uintptr_t>(spv.data()) + sizeof(uint8_t); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = reinterpret_cast<void*>(ptr); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidStage) { |
| TEST_DESCRIPTION("Create shader with invalid stage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-stage-08425"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_SUBPASS_SHADING_BIT_HUAWEI; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-stage-08426"); |
| |
| createInfo.stage = VK_SHADER_STAGE_CLUSTER_CULLING_BIT_HUAWEI; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, BindVertexAndTaskShaders) { |
| TEST_DESCRIPTION("Bind vertex and task shaders in the same call."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindShadersEXT-pShaders-08470"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_3, true, false)); |
| |
| const auto vert_spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| const auto task_spv = GLSLToSPV(VK_SHADER_STAGE_TASK_BIT_EXT, kTaskMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| |
| VkShaderCreateInfoEXT vertCreateInfo = vku::InitStructHelper(); |
| vertCreateInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| vertCreateInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| vertCreateInfo.codeSize = vert_spv.size() * sizeof(vert_spv[0]); |
| vertCreateInfo.pCode = vert_spv.data(); |
| vertCreateInfo.pName = "main"; |
| |
| VkShaderCreateInfoEXT taskCreateInfo = vku::InitStructHelper(); |
| taskCreateInfo.stage = VK_SHADER_STAGE_TASK_BIT_EXT; |
| taskCreateInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| taskCreateInfo.codeSize = task_spv.size() * sizeof(task_spv[0]); |
| taskCreateInfo.pCode = task_spv.data(); |
| taskCreateInfo.pName = "main"; |
| |
| vkt::Shader vert_shader(*m_device, vertCreateInfo); |
| vkt::Shader task_shader(*m_device, taskCreateInfo); |
| VkShaderEXT shaderHandles[] = { |
| vert_shader.handle(), |
| task_shader.handle(), |
| }; |
| |
| VkShaderStageFlagBits stages[] = { |
| VK_SHADER_STAGE_VERTEX_BIT, |
| VK_SHADER_STAGE_TASK_BIT_EXT, |
| }; |
| m_commandBuffer->begin(); |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 2u, stages, shaderHandles); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, BindVertexAndMeshShaders) { |
| TEST_DESCRIPTION("Bind vertex and mesh shaders in the same call."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindShadersEXT-pShaders-08471"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_3, false, true)); |
| |
| const auto vert_spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| const auto mesh_spv = GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| |
| VkShaderCreateInfoEXT vertCreateInfo = vku::InitStructHelper(); |
| vertCreateInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| vertCreateInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| vertCreateInfo.codeSize = vert_spv.size() * sizeof(vert_spv[0]); |
| vertCreateInfo.pCode = vert_spv.data(); |
| vertCreateInfo.pName = "main"; |
| |
| VkShaderCreateInfoEXT meshCreateInfo = vku::InitStructHelper(); |
| meshCreateInfo.stage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| meshCreateInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| meshCreateInfo.codeSize = mesh_spv.size() * sizeof(mesh_spv[0]); |
| meshCreateInfo.pCode = mesh_spv.data(); |
| meshCreateInfo.pName = "main"; |
| |
| vkt::Shader vert_shader(*m_device, vertCreateInfo); |
| vkt::Shader mesh_shader(*m_device, meshCreateInfo); |
| VkShaderEXT shaderHandles[] = { |
| vert_shader.handle(), |
| mesh_shader.handle(), |
| }; |
| |
| VkShaderStageFlagBits stages[] = { |
| VK_SHADER_STAGE_VERTEX_BIT, |
| VK_SHADER_STAGE_MESH_BIT_EXT, |
| }; |
| m_commandBuffer->begin(); |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 2u, stages, shaderHandles); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, CreateShadersWithoutEnabledFeatures) { |
| TEST_DESCRIPTION("Create tessellation shader without tessellationShader feature enabled."); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| |
| RETURN_IF_SKIP(InitFramework()); |
| VkPhysicalDeviceShaderObjectFeaturesEXT shaderObjectFeatures = vku::InitStructHelper(); |
| auto features2 = GetPhysicalDeviceFeatures2(shaderObjectFeatures); |
| features2.features.tessellationShader = VK_FALSE; |
| features2.features.geometryShader = VK_FALSE; |
| RETURN_IF_SKIP(InitState(nullptr, &features2)); |
| |
| { |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-stage-08419"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-pCode-08740"); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, kTessellationControlMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| vkt::Shader shader(*m_device, createInfo); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| { |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-stage-08420"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-pCode-08740"); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_GEOMETRY_BIT, kGeometryMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_GEOMETRY_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| vkt::Shader shader(*m_device, createInfo); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| TEST_F(NegativeShaderObject, CreateMeshShadersWithoutEnabledFeatures) { |
| TEST_DESCRIPTION("Create mesh and task shaders without features enabled."); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_MESH_SHADER_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_4_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::shaderObject); |
| AddRequiredFeature(vkt::Feature::maintenance4); |
| RETURN_IF_SKIP(Init()); |
| |
| { |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-stage-08421"); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_TASK_BIT_EXT, kTaskMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_TASK_BIT_EXT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| vkt::Shader shader(*m_device, createInfo); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| { |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-stage-08422"); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| vkt::Shader shader(*m_device, createInfo); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| TEST_F(NegativeShaderObject, ComputeShaderNotSupportedByCommandPool) { |
| TEST_DESCRIPTION("Use compute shaders with unsupported command pool."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindShadersEXT-pShaders-08476"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const std::optional<uint32_t> graphics_queue_family_index = m_device->QueueFamilyMatching(0u, VK_QUEUE_COMPUTE_BIT); |
| |
| if (!graphics_queue_family_index) { |
| GTEST_SKIP() << "No suitable queue found."; |
| } |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, kMinimalShaderGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| vkt::Shader shader(*m_device, createInfo); |
| VkShaderEXT shaderHandle = shader.handle(); |
| |
| vkt::CommandPool command_pool(*m_device, graphics_queue_family_index.value()); |
| vkt::CommandBuffer command_buffer(m_device, &command_pool); |
| command_buffer.begin(); |
| |
| vk::CmdBindShadersEXT(command_buffer.handle(), 1u, &createInfo.stage, &shaderHandle); |
| command_buffer.end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, GraphicsShadersNotSupportedByCommandPool) { |
| TEST_DESCRIPTION("Use graphics shaders with unsupported command pool."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindShadersEXT-pShaders-08477"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const std::optional<uint32_t> non_graphics_queue_family_index = m_device->QueueFamilyMatching(0u, VK_QUEUE_GRAPHICS_BIT); |
| |
| if (!non_graphics_queue_family_index) { |
| GTEST_SKIP() << "No suitable queue found."; |
| } |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| vkt::Shader shader(*m_device, createInfo); |
| VkShaderEXT shaderHandle = shader.handle(); |
| |
| vkt::CommandPool command_pool(*m_device, non_graphics_queue_family_index.value()); |
| vkt::CommandBuffer command_buffer(m_device, &command_pool); |
| command_buffer.begin(); |
| |
| vk::CmdBindShadersEXT(command_buffer.handle(), 1u, &createInfo.stage, &shaderHandle); |
| command_buffer.end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, GraphicsMeshShadersNotSupportedByCommandPool) { |
| TEST_DESCRIPTION("Use mesh shaders with unsupported command pool."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindShadersEXT-pShaders-08478"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_3, false, true)); |
| |
| const std::optional<uint32_t> non_graphics_queue_family_index = m_device->QueueFamilyMatching(0u, VK_QUEUE_GRAPHICS_BIT); |
| |
| if (!non_graphics_queue_family_index) { |
| GTEST_SKIP() << "No suitable queue found."; |
| } |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| vkt::Shader shader(*m_device, createInfo); |
| VkShaderEXT shaderHandle = shader.handle(); |
| |
| vkt::CommandPool command_pool(*m_device, non_graphics_queue_family_index.value()); |
| vkt::CommandBuffer command_buffer(m_device, &command_pool); |
| command_buffer.begin(); |
| |
| vk::CmdBindShadersEXT(command_buffer.handle(), 1u, &createInfo.stage, &shaderHandle); |
| command_buffer.end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, NonUniqueShadersBind) { |
| TEST_DESCRIPTION("Bind multiple shaders with same stage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindShadersEXT-pStages-08463"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| vkt::Shader shader1(*m_device, createInfo); |
| vkt::Shader shader2(*m_device, createInfo); |
| |
| VkShaderEXT shaders[] = { |
| shader1.handle(), |
| shader2.handle(), |
| }; |
| VkShaderStageFlagBits stages[] = { |
| VK_SHADER_STAGE_VERTEX_BIT, |
| VK_SHADER_STAGE_VERTEX_BIT, |
| }; |
| |
| m_commandBuffer->begin(); |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 2u, stages, shaders); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidShaderStageBind) { |
| TEST_DESCRIPTION("Bind shader with invalid stage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindShadersEXT-pShaders-08469"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindShadersEXT-pStages-08464"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| vkt::Shader shader(*m_device, createInfo); |
| VkShaderEXT shaderHandle = shader.handle(); |
| |
| VkShaderStageFlagBits stage = VK_SHADER_STAGE_ALL_GRAPHICS; |
| |
| m_commandBuffer->begin(); |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 1u, &stage, &shaderHandle); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, GetShaderBinaryDataInvalidPointer) { |
| TEST_DESCRIPTION("Get shader binary data with invalid pointer."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetShaderBinaryDataEXT-None-08499"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| if (IsPlatformMockICD()) { |
| GTEST_SKIP() << "Test not supported by MockICD"; |
| } |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| vkt::Shader shader(*m_device, createInfo); |
| VkShaderEXT shaderHandle = shader.handle(); |
| |
| size_t dataSize = 0; |
| vk::GetShaderBinaryDataEXT(m_device->handle(), shaderHandle, &dataSize, nullptr); |
| std::vector<uint8_t> data(dataSize + 1u); |
| auto ptr = reinterpret_cast<std::uintptr_t>(data.data()) + sizeof(uint8_t); |
| void* dataPtr = reinterpret_cast<void*>(ptr); |
| vk::GetShaderBinaryDataEXT(m_device->handle(), shaderHandle, &dataSize, dataPtr); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, DrawWithNoShadersBound) { |
| TEST_DESCRIPTION("Call vkCmdDraw when there are no shaders or pipeline bound."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08607"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08684"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08688"); |
| AddDisabledFeature(vkt::Feature::geometryShader); |
| AddDisabledFeature(vkt::Feature::tessellationShader); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| InitDynamicRenderTarget(); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, DrawWithMissingShaders) { |
| TEST_DESCRIPTION("Draw without setting all of the shader objects."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08607"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08687"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, |
| VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const VkShaderEXT shaders[] = {vertShader.handle(), VK_NULL_HANDLE, VK_NULL_HANDLE, fragShader.handle()}; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 4u, stages, shaders); |
| |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, DrawWithoutBindingMeshShadersWhenEnabled) { |
| TEST_DESCRIPTION("Draw without binding all of the shader objects supported by graphics."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08607"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08689"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08690"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_1, false, true)); |
| |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidShaderCreateInfoFlags) { |
| TEST_DESCRIPTION("Create shader with invalid flags."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-flags-08487"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.flags = VK_SHADER_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_EXT; |
| createInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-flags-08489"); |
| createInfo.flags = VK_SHADER_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingLinkStageBit) { |
| TEST_DESCRIPTION("Create a linked and non-linked shader in the same call."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateShadersEXT-pCreateInfos-08402"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto vert_spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| const auto frag_spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfos[2]; |
| createInfos[0] = vku::InitStructHelper(); |
| createInfos[0].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[0].stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfos[0].nextStage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfos[0].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[0].codeSize = vert_spv.size() * sizeof(vert_spv[0]); |
| createInfos[0].pCode = vert_spv.data(); |
| createInfos[0].pName = "main"; |
| createInfos[1] = vku::InitStructHelper(); |
| createInfos[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfos[1].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[1].codeSize = frag_spv.size() * sizeof(frag_spv[0]); |
| createInfos[1].pCode = frag_spv.data(); |
| createInfos[1].pName = "main"; |
| |
| VkShaderEXT shaders[2]; |
| vk::CreateShadersEXT(m_device->handle(), 2u, createInfos, nullptr, shaders); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingLinkStageBitMesh) { |
| TEST_DESCRIPTION("Create a linked and non-linked mesh shader in the same call."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateShadersEXT-pCreateInfos-08403"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_3, false, true)); |
| |
| const auto mesh_spv = GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| const auto frag_spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfos[2]; |
| createInfos[0] = vku::InitStructHelper(); |
| createInfos[0].stage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| createInfos[0].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[0].codeSize = mesh_spv.size() * sizeof(mesh_spv[0]); |
| createInfos[0].pCode = mesh_spv.data(); |
| createInfos[0].pName = "main"; |
| createInfos[1] = vku::InitStructHelper(); |
| createInfos[1].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfos[1].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[1].codeSize = frag_spv.size() * sizeof(frag_spv[0]); |
| createInfos[1].pCode = frag_spv.data(); |
| createInfos[1].pName = "main"; |
| |
| VkShaderEXT shaders[2]; |
| vk::CreateShadersEXT(m_device->handle(), 2u, createInfos, nullptr, shaders); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, LinkedVertexAndMeshStages) { |
| TEST_DESCRIPTION("Attempt to create linked vertex and mesh stages."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateShadersEXT-pCreateInfos-08404"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_3, false, true)); |
| |
| const auto vert_spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| const auto mesh_spv = GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| |
| VkShaderCreateInfoEXT createInfos[2]; |
| createInfos[0] = vku::InitStructHelper(); |
| createInfos[0].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[0].stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfos[0].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[0].codeSize = vert_spv.size() * sizeof(vert_spv[0]); |
| createInfos[0].pCode = vert_spv.data(); |
| createInfos[0].pName = "main"; |
| createInfos[1] = vku::InitStructHelper(); |
| createInfos[1].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[1].stage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| createInfos[1].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[1].codeSize = mesh_spv.size() * sizeof(mesh_spv[0]); |
| createInfos[1].pCode = mesh_spv.data(); |
| createInfos[1].pName = "main"; |
| |
| VkShaderEXT shaders[2]; |
| vk::CreateShadersEXT(m_device->handle(), 2u, createInfos, nullptr, shaders); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, LinkedTaskAndMeshNoTaskShaders) { |
| TEST_DESCRIPTION("Attempt to create linked task shader and linked mesh shader with no task shader flag."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateShadersEXT-pCreateInfos-08405"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_3, true, true)); |
| |
| const auto task_spv = GLSLToSPV(VK_SHADER_STAGE_TASK_BIT_EXT, kTaskMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| const auto mesh_spv = GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| |
| VkShaderCreateInfoEXT createInfos[2]; |
| createInfos[0] = vku::InitStructHelper(); |
| createInfos[0].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[0].stage = VK_SHADER_STAGE_TASK_BIT_EXT; |
| createInfos[0].nextStage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| createInfos[0].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[0].codeSize = task_spv.size() * sizeof(task_spv[0]); |
| createInfos[0].pCode = task_spv.data(); |
| createInfos[0].pName = "main"; |
| createInfos[1] = vku::InitStructHelper(); |
| createInfos[1].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT | VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT; |
| createInfos[1].stage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| createInfos[1].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[1].codeSize = mesh_spv.size() * sizeof(mesh_spv[0]); |
| createInfos[1].pCode = mesh_spv.data(); |
| createInfos[1].pName = "main"; |
| |
| VkShaderEXT shaders[2]; |
| vk::CreateShadersEXT(m_device->handle(), 2u, createInfos, nullptr, shaders); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingNextStage) { |
| TEST_DESCRIPTION("Attempt to linked vertex and fragment shaders with missing nextStage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateShadersEXT-pCreateInfos-08409"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto vert_spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| const auto frag_spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfos[2]; |
| createInfos[0] = vku::InitStructHelper(); |
| createInfos[0].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[0].stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfos[0].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[0].codeSize = vert_spv.size() * sizeof(vert_spv[0]); |
| createInfos[0].pCode = vert_spv.data(); |
| createInfos[0].pName = "main"; |
| createInfos[1] = vku::InitStructHelper(); |
| createInfos[1].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfos[1].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[1].codeSize = frag_spv.size() * sizeof(frag_spv[0]); |
| createInfos[1].pCode = frag_spv.data(); |
| createInfos[1].pName = "main"; |
| |
| VkShaderEXT shaders[2]; |
| vk::CreateShadersEXT(m_device->handle(), 2u, createInfos, nullptr, shaders); |
| |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateShadersEXT-pCreateInfos-08409"); |
| createInfos[0].nextStage = VK_SHADER_STAGE_GEOMETRY_BIT; |
| vk::CreateShadersEXT(m_device->handle(), 2u, createInfos, nullptr, shaders); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, SameLinkedStage) { |
| TEST_DESCRIPTION("Create multiple linked shaders with the same stage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateShadersEXT-pCreateInfos-08410"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfos[2]; |
| createInfos[0] = vku::InitStructHelper(); |
| createInfos[0].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[0].stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfos[0].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[0].codeSize = spv.size() * sizeof(spv[0]); |
| createInfos[0].pCode = spv.data(); |
| createInfos[0].pName = "main"; |
| createInfos[1] = vku::InitStructHelper(); |
| createInfos[1].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[1].stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfos[1].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[1].codeSize = spv.size() * sizeof(spv[0]); |
| createInfos[1].pCode = spv.data(); |
| createInfos[1].pName = "main"; |
| |
| VkShaderEXT shaders[2]; |
| vk::CreateShadersEXT(m_device->handle(), 2u, createInfos, nullptr, shaders); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, LinkedStagesWithDifferentCodeType) { |
| TEST_DESCRIPTION("Create linked shaders with different code types."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateShadersEXT-pCreateInfos-08411"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| if (IsPlatformMockICD()) { |
| GTEST_SKIP() << "Test not supported by MockICD"; |
| } |
| |
| const auto vert_spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| const auto frag_spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfos[2]; |
| createInfos[0] = vku::InitStructHelper(); |
| createInfos[0].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[0].stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfos[0].nextStage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfos[0].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[0].codeSize = vert_spv.size() * sizeof(vert_spv[0]); |
| createInfos[0].pCode = vert_spv.data(); |
| createInfos[0].pName = "main"; |
| createInfos[1] = vku::InitStructHelper(); |
| createInfos[1].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfos[1].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[1].codeSize = frag_spv.size() * sizeof(frag_spv[0]); |
| createInfos[1].pCode = frag_spv.data(); |
| createInfos[1].pName = "main"; |
| |
| VkShaderEXT shaders[2]; |
| vk::CreateShadersEXT(m_device->handle(), 2u, createInfos, nullptr, shaders); |
| |
| size_t dataSize = 0u; |
| vk::GetShaderBinaryDataEXT(m_device->handle(), shaders[0], &dataSize, nullptr); |
| std::vector<uint8_t> binaryData(dataSize); |
| vk::GetShaderBinaryDataEXT(m_device->handle(), shaders[0], &dataSize, binaryData.data()); |
| |
| createInfos[0].codeType = VK_SHADER_CODE_TYPE_BINARY_EXT; |
| createInfos[0].codeSize = dataSize; |
| createInfos[0].pCode = binaryData.data(); |
| |
| vk::CreateShadersEXT(m_device->handle(), 2u, createInfos, nullptr, shaders); |
| |
| for (uint32_t i = 0; i < 2; ++i) { |
| vk::DestroyShaderEXT(m_device->handle(), shaders[i], nullptr); |
| } |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, UnsupportedNextStage) { |
| TEST_DESCRIPTION("Create shader with unsupported next stage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-nextStage-08428"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitFramework()); |
| |
| VkPhysicalDeviceDynamicRenderingFeatures dynamic_rendering_features = vku::InitStructHelper(); |
| VkPhysicalDeviceShaderObjectFeaturesEXT shaderObjectFeatures = vku::InitStructHelper(&dynamic_rendering_features); |
| auto features2 = GetPhysicalDeviceFeatures2(shaderObjectFeatures); |
| if (!shaderObjectFeatures.shaderObject) { |
| GTEST_SKIP() << "Test requires (unsupported) shaderObject , skipping."; |
| } |
| features2.features.tessellationShader = VK_FALSE; |
| features2.features.geometryShader = VK_FALSE; |
| |
| RETURN_IF_SKIP(InitState(nullptr, &features2)); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.nextStage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-nextStage-08429"); |
| createInfo.nextStage = VK_SHADER_STAGE_GEOMETRY_BIT; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidTessellationControlNextStage) { |
| TEST_DESCRIPTION("Create tessellation control shader with invalid nextStage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-nextStage-08430"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, kTessellationControlMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; |
| createInfo.nextStage = VK_SHADER_STAGE_GEOMETRY_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidTessellationEvaluationNextStage) { |
| TEST_DESCRIPTION("Create tessellation evaluation shader with invalid nextStage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-nextStage-08431"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, kTessellationEvalMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| createInfo.nextStage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidGeometryNextStage) { |
| TEST_DESCRIPTION("Create geometry shader with invalid nextStage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-nextStage-08433"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_GEOMETRY_BIT, kGeometryMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_GEOMETRY_BIT; |
| createInfo.nextStage = VK_SHADER_STAGE_GEOMETRY_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidFragmentNextStage) { |
| TEST_DESCRIPTION("Create fragment shader with invalid nextStage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-nextStage-08434"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfo.nextStage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidTaskNextStage) { |
| TEST_DESCRIPTION("Create task shader with invalid nextStage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-nextStage-08435"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_1, true, true)); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_TASK_BIT_EXT, kTaskMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_TASK_BIT_EXT; |
| createInfo.nextStage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidMeshNextStage) { |
| TEST_DESCRIPTION("Create mesh shader with invalid nextStage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-nextStage-08436"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_1, false, true)); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| createInfo.nextStage = VK_SHADER_STAGE_GEOMETRY_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, BindInvalidShaderStage) { |
| TEST_DESCRIPTION("Bind shader with different stage than it was created with."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindShadersEXT-pShaders-08469"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| VkShaderStageFlagBits stage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| |
| m_commandBuffer->begin(); |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 1u, &stage, &vertShader.handle()); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, DrawWithShadersOutsideRenderPass) { |
| TEST_DESCRIPTION("Draw with shaders outside of a render pass."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-renderpass"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, DrawWithShadersInNonDynamicRenderPass) { |
| TEST_DESCRIPTION("Draw with shaders inside a non-dynamic render pass."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08876"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentMinimalGlsl)); |
| |
| RenderPassSingleSubpass rp(*this); |
| rp.AddAttachmentDescription(VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_UNDEFINED); |
| rp.AddAttachmentReference({0, VK_IMAGE_LAYOUT_GENERAL}); |
| rp.AddColorAttachment(0); |
| rp.CreateRenderPass(); |
| |
| VkImageObj image(m_device); |
| image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::ImageView image_view = image.CreateView(); |
| vkt::Framebuffer framebuffer(*m_device, rp.Handle(), 1, &image_view.handle()); |
| |
| VkClearValue clear_value; |
| clear_value.color.float32[0] = 0.25f; |
| clear_value.color.float32[1] = 0.25f; |
| clear_value.color.float32[2] = 0.25f; |
| clear_value.color.float32[3] = 0.0f; |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderPass(rp.Handle(), framebuffer.handle(), 32, 32, 1, &clear_value); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->EndRenderPass(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, IncompatibleDescriptorSet) { |
| TEST_DESCRIPTION("Bind an incompatible descriptor set."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08600"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08600"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| static const char vertSource[] = R"glsl( |
| #version 460 |
| layout(set = 0, binding = 1) buffer foo { |
| int x; |
| } bar; |
| void main() { |
| gl_Position = vec4(bar.x); |
| } |
| )glsl"; |
| |
| OneOffDescriptorSet descriptor_set(m_device, |
| { |
| {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}, |
| {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, nullptr}, |
| }); |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], vertSource), &descriptor_set.layout_.handle()); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentUniformGlsl), |
| &descriptor_set.layout_.handle()); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, NotSettingViewportAndScissor) { |
| TEST_DESCRIPTION("Draw with shader object without setting viewport and scissor."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08635"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, DifferentViewportAndScissorCount) { |
| TEST_DESCRIPTION("Draw with shader object with different viewport and scissor count."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08635"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| VkViewport viewports[2]; |
| viewports[0] = {0.0f, 0.0f, 100.0f, 100.0f, 0.0f, 1.0f}; |
| viewports[1] = {0.0f, 100.0f, 100.0f, 100.0f, 0.0f, 1.0f}; |
| vk::CmdSetViewportWithCountEXT(m_commandBuffer->handle(), 2u, viewports); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidViewportWScaling) { |
| TEST_DESCRIPTION("Draw with shader object with invalid viewport count in vkCmdSetViewportWScaling."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08636"); |
| |
| AddRequiredExtensions(VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| VkViewport viewports[2]; |
| viewports[0] = {0.0f, 0.0f, 100.0f, 100.0f, 0.0f, 1.0f}; |
| viewports[1] = {0.0f, 100.0f, 100.0f, 100.0f, 0.0f, 1.0f}; |
| vk::CmdSetViewportWithCountEXT(m_commandBuffer->handle(), 2u, viewports); |
| VkRect2D scissors[2]; |
| scissors[0] = {{0, 0}, {100u, 100u}}; |
| scissors[1] = {{0, 100}, {100u, 100u}}; |
| vk::CmdSetScissorWithCountEXT(m_commandBuffer->handle(), 2u, scissors); |
| VkViewportWScalingNV viewportWScaling = {1.0f, 1.0f}; |
| vk::CmdSetViewportWScalingEnableNV(m_commandBuffer->handle(), VK_TRUE); |
| vk::CmdSetViewportWScalingNV(m_commandBuffer->handle(), 0u, 1u, &viewportWScaling); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidShadingRatePaletteViewportCount) { |
| TEST_DESCRIPTION("Draw with shader object with invalid viewport count in vkCmdSetViewportShadingRatePaletteNV."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08637"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitFramework()); |
| VkPhysicalDeviceShadingRateImageFeaturesNV shading_rate_image_features_nv = vku::InitStructHelper(); |
| VkPhysicalDeviceDynamicRenderingFeatures dynamic_rendering_features = vku::InitStructHelper(&shading_rate_image_features_nv); |
| VkPhysicalDeviceShaderObjectFeaturesEXT shader_object_features = vku::InitStructHelper(&dynamic_rendering_features); |
| auto features2 = GetPhysicalDeviceFeatures2(shader_object_features); |
| RETURN_IF_SKIP(InitState(nullptr, &features2)); |
| if (shading_rate_image_features_nv.shadingRateImage == VK_FALSE) { |
| GTEST_SKIP() << "shadingRateImage not supported."; |
| } |
| |
| InitDynamicRenderTarget(); |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| VkViewport viewports[2]; |
| viewports[0] = {0.0f, 0.0f, 100.0f, 100.0f, 0.0f, 1.0f}; |
| viewports[1] = {0.0f, 100.0f, 100.0f, 100.0f, 0.0f, 1.0f}; |
| vk::CmdSetViewportWithCountEXT(m_commandBuffer->handle(), 2u, viewports); |
| VkRect2D scissors[2]; |
| scissors[0] = {{0, 0}, {100u, 100u}}; |
| scissors[1] = {{0, 100}, {100u, 100u}}; |
| vk::CmdSetScissorWithCountEXT(m_commandBuffer->handle(), 2u, scissors); |
| VkShadingRatePaletteEntryNV defaultShadingRatePaletteEntry = VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV; |
| VkShadingRatePaletteNV shadingRatePalette; |
| shadingRatePalette.shadingRatePaletteEntryCount = 1u; |
| shadingRatePalette.pShadingRatePaletteEntries = &defaultShadingRatePaletteEntry; |
| vk::CmdSetShadingRateImageEnableNV(m_commandBuffer->handle(), VK_TRUE); |
| vk::CmdSetViewportShadingRatePaletteNV(m_commandBuffer->handle(), 0u, 1u, &shadingRatePalette); |
| vk::CmdSetCoarseSampleOrderNV(m_commandBuffer->handle(), VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV, 0u, nullptr); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetExclusiveScissorEnableNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetExclusiveScissorEnableNV."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-exclusiveScissor-09235"); |
| |
| AddRequiredExtensions(VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::exclusiveScissor); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidExclusiveScissorCount) { |
| TEST_DESCRIPTION("Draw with shader object with invalid viewport count in vkCmdSetExclusiveScissorNV."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08638"); |
| |
| AddRequiredExtensions(VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::exclusiveScissor); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| uint32_t count; |
| vk::EnumerateDeviceExtensionProperties(m_device->phy(), nullptr, &count, nullptr); |
| std::vector<VkExtensionProperties> properties(count); |
| vk::EnumerateDeviceExtensionProperties(m_device->phy(), nullptr, &count, properties.data()); |
| for (const auto& p : properties) { |
| if (std::strcmp(p.extensionName, VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME) == 0) { |
| if (p.specVersion < 2) { |
| GTEST_SKIP() << "exclusiveScissor specVersion 2 not supported."; |
| } |
| } |
| } |
| InitDynamicRenderTarget(); |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| VkViewport viewports[2]; |
| viewports[0] = {0.0f, 0.0f, 100.0f, 100.0f, 0.0f, 1.0f}; |
| viewports[1] = {0.0f, 100.0f, 100.0f, 100.0f, 0.0f, 1.0f}; |
| vk::CmdSetViewportWithCountEXT(m_commandBuffer->handle(), 2u, viewports); |
| VkRect2D scissors[2]; |
| scissors[0] = {{0, 0}, {100u, 100u}}; |
| scissors[1] = {{0, 100}, {100u, 100u}}; |
| vk::CmdSetScissorWithCountEXT(m_commandBuffer->handle(), 2u, scissors); |
| VkBool32 exclusiveScissorEnable = VK_TRUE; |
| vk::CmdSetExclusiveScissorEnableNV(m_commandBuffer->handle(), 0u, 1u, &exclusiveScissorEnable); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetRasterizerDiscardEnable) { |
| TEST_DESCRIPTION("Draw with shaders without setting vkCmdSetRasterizerDiscardEnable."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08639"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthBiasEnable) { |
| TEST_DESCRIPTION("Draw with shaders without setting vkCmdSetDepthBiasEnable."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08640"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetLogicOp) { |
| TEST_DESCRIPTION("Draw with shaders without setting vkCmdSetLogicOp."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08641"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::shaderObject); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::logicOp); |
| RETURN_IF_SKIP(Init()); |
| InitDynamicRenderTarget(); |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_LOGIC_OP_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdSetLogicOpEnableEXT(m_commandBuffer->handle(), VK_TRUE); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, BlendEnabledWithNonBlendableFormat) { |
| TEST_DESCRIPTION("Draw with shader objects with blend enabled for attachment format that does not support blending."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08643"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| VkFormatProperties props; |
| vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_R32_UINT, &props); |
| |
| if ((props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0 || |
| (props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) != 0) { |
| GTEST_SKIP() << "color attachment format not suitable."; |
| } |
| |
| InitDynamicRenderTarget(VK_FORMAT_R32_UINT); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| VkBool32 enabled = VK_TRUE; |
| vk::CmdSetColorBlendEnableEXT(m_commandBuffer->handle(), 0, 1, &enabled); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, RasterizationSamplesMismatch) { |
| TEST_DESCRIPTION("Draw with shader objects with invalid rasterization samples in vkCmdSetRasterizationSamplesEXT()."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08644"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdSetRasterizationSamplesEXT(m_commandBuffer->handle(), VK_SAMPLE_COUNT_2_BIT); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingColorWriteEnable) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetColorWriteEnableEXT()."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08646"); |
| |
| AddRequiredExtensions(VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::colorWriteEnable); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, ColorWriteEnableAttachmentCount) { |
| TEST_DESCRIPTION("Draw with shader objects without setting color write enable for all attachments."); |
| |
| AddRequiredExtensions(VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::colorWriteEnable); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| VkImageObj img1(m_device); |
| img1.Init(m_width, m_height, 1, m_render_target_fmt, |
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| VkImageObj img2(m_device); |
| img2.Init(m_width, m_height, 1, m_render_target_fmt, |
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| |
| vkt::ImageView view1 = img1.CreateView(); |
| vkt::ImageView view2 = img2.CreateView(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| |
| VkRenderingAttachmentInfo attachments[2]; |
| attachments[0] = vku::InitStructHelper(); |
| attachments[0].imageView = view1; |
| attachments[0].imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachments[1] = vku::InitStructHelper(); |
| attachments[1].imageView = view2; |
| attachments[1].imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| |
| VkRenderingInfoKHR renderingInfo = vku::InitStructHelper(); |
| renderingInfo.renderArea = {{0, 0}, {100u, 100u}}; |
| renderingInfo.layerCount = 1u; |
| renderingInfo.colorAttachmentCount = 2u; |
| renderingInfo.pColorAttachments = attachments; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08647"); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRendering(renderingInfo); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| VkBool32 colorWriteEnable = VK_TRUE; |
| vk::CmdSetColorWriteEnableEXT(m_commandBuffer->handle(), 1u, &colorWriteEnable); |
| VkColorComponentFlags colorWriteMask = |
| VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; |
| vk::CmdSetColorWriteMaskEXT(m_commandBuffer->handle(), 1u, 1u, &colorWriteMask); |
| VkBool32 colorBlendEnable = VK_FALSE; |
| vk::CmdSetColorBlendEnableEXT(m_commandBuffer->handle(), 1u, 1u, &colorBlendEnable); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDiscardRectangleEnableEXT) { |
| TEST_DESCRIPTION("Draw with shaders without setting vkCmdSetDiscardRectangleEnableEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08648"); |
| |
| AddRequiredExtensions(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDiscardRectangleModeEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDiscardRectangleModeEXT()."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08649"); |
| |
| AddRequiredExtensions(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| uint32_t count; |
| vk::EnumerateDeviceExtensionProperties(m_device->phy(), nullptr, &count, nullptr); |
| std::vector<VkExtensionProperties> properties(count); |
| vk::EnumerateDeviceExtensionProperties(m_device->phy(), nullptr, &count, properties.data()); |
| for (const auto& p : properties) { |
| if (std::strcmp(p.extensionName, VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME) == 0) { |
| if (p.specVersion < 2) { |
| GTEST_SKIP() << "discard rectangles specVersion 2 not supported."; |
| } |
| } |
| } |
| |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| vk::CmdSetDiscardRectangleEnableEXT(m_commandBuffer->handle(), VK_TRUE); |
| VkRect2D discardRectangle; |
| discardRectangle.offset = {}; |
| discardRectangle.extent = {100u, 100u}; |
| vk::CmdSetDiscardRectangleEXT(m_commandBuffer->handle(), 0u, 1u, &discardRectangle); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDiscardRectangleEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDiscardRectangleEXT()."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-rasterizerDiscardEnable-09236"); |
| |
| AddRequiredExtensions(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| uint32_t count; |
| vk::EnumerateDeviceExtensionProperties(m_device->phy(), nullptr, &count, nullptr); |
| std::vector<VkExtensionProperties> properties(count); |
| vk::EnumerateDeviceExtensionProperties(m_device->phy(), nullptr, &count, properties.data()); |
| for (const auto& p : properties) { |
| if (std::strcmp(p.extensionName, VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME) == 0) { |
| if (p.specVersion < 2) { |
| GTEST_SKIP() << "discard rectangles specVersion 2 not supported."; |
| } |
| } |
| } |
| |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| vk::CmdSetDiscardRectangleEnableEXT(m_commandBuffer->handle(), VK_TRUE); |
| vk::CmdSetDiscardRectangleModeEXT(m_commandBuffer->handle(), VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthClampEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDepthClampEnableEXT()."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08650"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetPolygonModeEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetPolygonModeEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08651"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_POLYGON_MODE_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetRasterizationSamplesEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetRasterizationSamplesEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08652"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetSampleMaskEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetSampleMaskEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08653"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_SAMPLE_MASK_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetAlphaToCoverageEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetAlphaToCoverageEnableEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08654"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetAlphaToOneEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetAlphaToOneEnableEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08655"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetLogicOpEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetLogicOpEnableEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08656"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::shaderObject); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::logicOp); |
| RETURN_IF_SKIP(Init()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetColorBlendEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetColorBlendEnableEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08657"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-rasterizerDiscardEnable-09417"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetColorBlendEnableEXTForActiveAttachment) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetColorBlendEnableEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-rasterizerDiscardEnable-09417"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| VkBool32 enable = VK_TRUE; |
| vk::CmdSetColorBlendEnableEXT(m_commandBuffer->handle(), 1u, 1u, &enable); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetColorBlendEquationEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetColorBlendEquationEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08658"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-rasterizerDiscardEnable-09418"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| VkBool32 colorBlendEnable = VK_TRUE; |
| vk::CmdSetColorBlendEnableEXT(m_commandBuffer->handle(), 0u, 1u, &colorBlendEnable); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetColorBlendEquationEXTActiveAttachments) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetColorBlendEquationEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08658"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| VkBool32 colorBlendEnable = VK_TRUE; |
| vk::CmdSetColorBlendEnableEXT(m_commandBuffer->handle(), 0u, 1u, &colorBlendEnable); |
| VkColorBlendEquationEXT colorBlendEquation = { |
| VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ONE, VK_BLEND_OP_ADD, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ONE, VK_BLEND_OP_ADD, |
| }; |
| vk::CmdSetColorBlendEquationEXT(m_commandBuffer->handle(), 1u, 1u, &colorBlendEquation); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetColorBlendAdvancedEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetColorBlendAdvancedEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08658"); |
| |
| AddRequiredExtensions(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT}); |
| VkBool32 colorBlendEnable = VK_TRUE; |
| vk::CmdSetColorBlendEnableEXT(m_commandBuffer->handle(), 0u, 1u, &colorBlendEnable); |
| VkColorBlendAdvancedEXT colorBlendAdvanced; |
| colorBlendAdvanced.advancedBlendOp = VK_BLEND_OP_ADD; |
| colorBlendAdvanced.srcPremultiplied = VK_FALSE; |
| colorBlendAdvanced.dstPremultiplied = VK_FALSE; |
| colorBlendAdvanced.blendOverlap = VK_BLEND_OVERLAP_UNCORRELATED_EXT; |
| colorBlendAdvanced.clampResults = VK_FALSE; |
| vk::CmdSetColorBlendAdvancedEXT(m_commandBuffer->handle(), 0u, 1u, &colorBlendAdvanced); |
| VkColorBlendEquationEXT colorBlendEquation = { |
| VK_BLEND_FACTOR_CONSTANT_COLOR, |
| VK_BLEND_FACTOR_ONE, |
| VK_BLEND_OP_ADD, |
| VK_BLEND_FACTOR_ONE, |
| VK_BLEND_FACTOR_ONE, |
| VK_BLEND_OP_ADD, |
| }; |
| vk::CmdSetColorBlendEquationEXT(m_commandBuffer->handle(), 1u, 1u, &colorBlendEquation); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetFragmentShadingRateKHR) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetFragmentShadingRateKHR."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-pipelineFragmentShadingRate-09238"); |
| |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineFragmentShadingRate); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetColorWriteMaskEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetColorWriteMaskEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08659"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-rasterizerDiscardEnable-09419"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetColorWriteMaskEXTActiveAttachments) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetColorWriteMaskEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-rasterizerDiscardEnable-09419"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| VkColorComponentFlags colorWriteMask = VK_COLOR_COMPONENT_R_BIT; |
| vk::CmdSetColorWriteMaskEXT(m_commandBuffer->handle(), 1u, 1u, &colorWriteMask); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetRasterizationStreamEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetRasterizationStreamEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08660"); |
| |
| AddRequiredExtensions(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::geometryStreams); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| const vkt::Shader geomShader(*m_device, VK_SHADER_STAGE_GEOMETRY_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_GEOMETRY_BIT, kGeometryMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, |
| VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, VK_SHADER_STAGE_GEOMETRY_BIT, |
| VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const VkShaderEXT shaders[] = {vertShader.handle(), VK_NULL_HANDLE, VK_NULL_HANDLE, geomShader.handle(), fragShader.handle()}; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 5u, stages, shaders); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetConservativeRasterizationModeEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetConservativeRasterizationModeEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08661"); |
| |
| AddRequiredExtensions(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetExtraPrimitiveOverestimationSizeEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetExtraPrimitiveOverestimationSizeEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08662"); |
| |
| AddRequiredExtensions(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| vk::CmdSetConservativeRasterizationModeEXT(m_commandBuffer->handle(), VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthClipEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDepthClipEnableEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08663"); |
| |
| AddRequiredExtensions(VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::depthClipEnable); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetSampleLocationsEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetSampleLocationsEnableEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08664"); |
| |
| AddRequiredExtensions(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetProvokingVertexModeEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetProvokingVertexModeEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08665"); |
| |
| AddRequiredExtensions(VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingPolygonModeCmdSetLineRasterizationModeEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetLineRasterizationModeEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08666"); |
| |
| AddRequiredExtensions(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| vk::CmdSetPolygonModeEXT(m_commandBuffer->handle(), VK_POLYGON_MODE_LINE); |
| vk::CmdSetLineStippleEnableEXT(m_commandBuffer->handle(), VK_FALSE); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingPrimitiveTopologyCmdSetLineRasterizationModeEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetLineRasterizationModeEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08667"); |
| |
| AddRequiredExtensions(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| vk::CmdSetPrimitiveTopologyEXT(m_commandBuffer->handle(), VK_PRIMITIVE_TOPOLOGY_LINE_LIST); |
| vk::CmdSetLineStippleEnableEXT(m_commandBuffer->handle(), VK_FALSE); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingPolygonModeCmdSetLineStippleEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetLineStippleEnableEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08669"); |
| |
| AddRequiredExtensions(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| vk::CmdSetPolygonModeEXT(m_commandBuffer->handle(), VK_POLYGON_MODE_LINE); |
| vk::CmdSetLineRasterizationModeEXT(m_commandBuffer->handle(), VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingPrimitiveTopologyCmdSetLineStippleEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetLineStippleEnableEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08670"); |
| |
| AddRequiredExtensions(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| vk::CmdSetPrimitiveTopologyEXT(m_commandBuffer->handle(), VK_PRIMITIVE_TOPOLOGY_LINE_LIST); |
| vk::CmdSetLineRasterizationModeEXT(m_commandBuffer->handle(), VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetLineStippleEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetLineStippleEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08672"); |
| |
| AddRequiredExtensions(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| vk::CmdSetLineStippleEnableEXT(m_commandBuffer->handle(), VK_TRUE); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthClipNegativeOneToOneEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDepthClipNegativeOneToOneEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08673"); |
| |
| AddRequiredExtensions(VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::depthClipControl); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetViewportWScalingEnableNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetViewportWScalingEnableNV."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08674"); |
| |
| AddRequiredExtensions(VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetViewportWScalingNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetViewportWScalingNV."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-09232"); |
| |
| AddRequiredExtensions(VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| vk::CmdSetViewportWScalingEnableNV(m_commandBuffer->handle(), VK_TRUE); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetViewportSwizzleNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetViewportSwizzleNV."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08675"); |
| |
| AddRequiredExtensions(VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetCoverageToColorEnableNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetCoverageToColorEnableNV."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08676"); |
| |
| AddRequiredExtensions(VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetCoverageToColorLocationNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetCoverageToColorLocationNV."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08677"); |
| |
| AddRequiredExtensions(VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| vk::CmdSetCoverageToColorEnableNV(m_commandBuffer->handle(), VK_TRUE); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetCoverageModulationModeNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetCoverageModulationModeNV."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08678"); |
| |
| AddRequiredExtensions(VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| vk::CmdSetCoverageModulationTableEnableNV(m_commandBuffer->handle(), VK_FALSE); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetCoverageModulationTableEnableNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetCoverageModulationTableEnableNV."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08679"); |
| |
| AddRequiredExtensions(VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| vk::CmdSetCoverageModulationModeNV(m_commandBuffer->handle(), VK_COVERAGE_MODULATION_MODE_RGBA_NV); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetCoverageModulationTableNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetCoverageModulationTableNV."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08680"); |
| |
| AddRequiredExtensions(VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| vk::CmdSetCoverageModulationModeNV(m_commandBuffer->handle(), VK_COVERAGE_MODULATION_MODE_NONE_NV); |
| vk::CmdSetCoverageModulationTableEnableNV(m_commandBuffer->handle(), VK_TRUE); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetShadingRateImageEnableNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetShadingRateImageEnableNV."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08681"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitFramework()); |
| VkPhysicalDeviceShadingRateImageFeaturesNV shading_rate_image_features_nv = vku::InitStructHelper(); |
| VkPhysicalDeviceDynamicRenderingFeatures dynamic_rendering_features = vku::InitStructHelper(&shading_rate_image_features_nv); |
| VkPhysicalDeviceShaderObjectFeaturesEXT shader_object_features = vku::InitStructHelper(&dynamic_rendering_features); |
| auto features2 = GetPhysicalDeviceFeatures2(shader_object_features); |
| RETURN_IF_SKIP(InitState(nullptr, &features2)); |
| if (shading_rate_image_features_nv.shadingRateImage == VK_FALSE) { |
| GTEST_SKIP() << "shadingRateImage not supported."; |
| } |
| |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| vk::CmdSetCoarseSampleOrderNV(m_commandBuffer->handle(), VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV, 0u, nullptr); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetViewportShadingRatePaletteNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetViewportShadingRatePaletteNV."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-shadingRateImage-09234"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitFramework()); |
| VkPhysicalDeviceShadingRateImageFeaturesNV shading_rate_image_features_nv = vku::InitStructHelper(); |
| VkPhysicalDeviceDynamicRenderingFeatures dynamic_rendering_features = vku::InitStructHelper(&shading_rate_image_features_nv); |
| VkPhysicalDeviceShaderObjectFeaturesEXT shader_object_features = vku::InitStructHelper(&dynamic_rendering_features); |
| auto features2 = GetPhysicalDeviceFeatures2(shader_object_features); |
| RETURN_IF_SKIP(InitState(nullptr, &features2)); |
| if (shading_rate_image_features_nv.shadingRateImage == VK_FALSE) { |
| GTEST_SKIP() << "shadingRateImage not supported."; |
| } |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| vk::CmdSetCoarseSampleOrderNV(m_commandBuffer->handle(), VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV, 0u, nullptr); |
| vk::CmdSetShadingRateImageEnableNV(m_commandBuffer->handle(), VK_TRUE); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetCoarseSampleOrderNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetCoarseSampleOrderNV."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-shadingRateImage-09233"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitFramework()); |
| VkPhysicalDeviceShadingRateImageFeaturesNV shading_rate_image_features_nv = vku::InitStructHelper(); |
| VkPhysicalDeviceDynamicRenderingFeatures dynamic_rendering_features = vku::InitStructHelper(&shading_rate_image_features_nv); |
| VkPhysicalDeviceShaderObjectFeaturesEXT shader_object_features = vku::InitStructHelper(&dynamic_rendering_features); |
| auto features2 = GetPhysicalDeviceFeatures2(shader_object_features); |
| RETURN_IF_SKIP(InitState(nullptr, &features2)); |
| if (shading_rate_image_features_nv.shadingRateImage == VK_FALSE) { |
| GTEST_SKIP() << "shadingRateImage not supported."; |
| } |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| vk::CmdSetShadingRateImageEnableNV(m_commandBuffer->handle(), VK_FALSE); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetRepresentativeFragmentTestEnableNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetRepresentativeFragmentTestEnableNV."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08682"); |
| |
| AddRequiredExtensions(VK_NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::representativeFragmentTest); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetCoverageReductionModeNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetCoverageReductionModeNV."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08683"); |
| |
| AddRequiredExtensions(VK_NV_COVERAGE_REDUCTION_MODE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::coverageReductionMode); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| vk::CmdSetCoverageModulationModeNV(m_commandBuffer->handle(), VK_COVERAGE_MODULATION_MODE_NONE_NV); |
| vk::CmdSetCoverageModulationTableEnableNV(m_commandBuffer->handle(), VK_FALSE); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingVertexShaderBind) { |
| TEST_DESCRIPTION("Draw with shader objects without binding vertex shader."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08607"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08684"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, |
| VK_SHADER_STAGE_GEOMETRY_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const VkShaderEXT shaders[] = {VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, fragShader.handle()}; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 4u, stages, shaders); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingTessellationControlBind) { |
| TEST_DESCRIPTION("Draw with shader objects without binding tessellation control shader."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08607"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08685"); |
| |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitFramework()); |
| |
| VkPhysicalDeviceDynamicRenderingFeatures dynamic_rendering_features = vku::InitStructHelper(); |
| VkPhysicalDeviceShaderObjectFeaturesEXT shaderObjectFeatures = vku::InitStructHelper(&dynamic_rendering_features); |
| auto features2 = GetPhysicalDeviceFeatures2(shaderObjectFeatures); |
| if (!shaderObjectFeatures.shaderObject) { |
| GTEST_SKIP() << "shaderObject not supported."; |
| } |
| if (features2.features.tessellationShader == VK_FALSE) { |
| GTEST_SKIP() << "tessellationShader not supported."; |
| } |
| RETURN_IF_SKIP(InitState(nullptr, &features2)); |
| |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, |
| VK_SHADER_STAGE_GEOMETRY_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const VkShaderEXT shaders[] = {vertShader.handle(), VK_NULL_HANDLE, VK_NULL_HANDLE, fragShader.handle()}; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 4u, stages, shaders); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingTessellationEvaluationBind) { |
| TEST_DESCRIPTION("Draw with shader objects without binding tessellation evaluation shader."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08607"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08686"); |
| |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitFramework()); |
| |
| VkPhysicalDeviceDynamicRenderingFeatures dynamic_rendering_features = vku::InitStructHelper(); |
| VkPhysicalDeviceShaderObjectFeaturesEXT shaderObjectFeatures = vku::InitStructHelper(&dynamic_rendering_features); |
| auto features2 = GetPhysicalDeviceFeatures2(shaderObjectFeatures); |
| if (!shaderObjectFeatures.shaderObject) { |
| GTEST_SKIP() << "shaderObject not supported."; |
| } |
| if (features2.features.tessellationShader == VK_FALSE) { |
| GTEST_SKIP() << "tessellationShader not supported."; |
| } |
| RETURN_IF_SKIP(InitState(nullptr, &features2)); |
| |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, |
| VK_SHADER_STAGE_GEOMETRY_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const VkShaderEXT shaders[] = {vertShader.handle(), VK_NULL_HANDLE, VK_NULL_HANDLE, fragShader.handle()}; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 4u, stages, shaders); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingGeometryBind) { |
| TEST_DESCRIPTION("Draw with shader objects without binding geometry shader."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08607"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08687"); |
| |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitFramework()); |
| |
| VkPhysicalDeviceDynamicRenderingFeatures dynamic_rendering_features = vku::InitStructHelper(); |
| VkPhysicalDeviceShaderObjectFeaturesEXT shaderObjectFeatures = vku::InitStructHelper(&dynamic_rendering_features); |
| auto features2 = GetPhysicalDeviceFeatures2(shaderObjectFeatures); |
| if (!shaderObjectFeatures.shaderObject) { |
| GTEST_SKIP() << "shaderObject not supported."; |
| } |
| if (features2.features.geometryShader == VK_FALSE) { |
| GTEST_SKIP() << "geometryShader not supported."; |
| } |
| RETURN_IF_SKIP(InitState(nullptr, &features2)); |
| |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, |
| VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const VkShaderEXT shaders[] = {vertShader.handle(), VK_NULL_HANDLE, VK_NULL_HANDLE, fragShader.handle()}; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 4u, stages, shaders); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingFragmentShaderBind) { |
| TEST_DESCRIPTION("Draw with shader objects without binding fragment shader."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08607"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08688"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, |
| VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, VK_SHADER_STAGE_GEOMETRY_BIT}; |
| const VkShaderEXT shaders[] = {vertShader.handle(), VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE}; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 4u, stages, shaders); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingTaskShaderBind) { |
| TEST_DESCRIPTION("Draw with shader objects without binding task shader."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08607"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08689"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_1, true, true)); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| { |
| VkShaderStageFlagBits meshStage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| VkShaderEXT nullShader = VK_NULL_HANDLE; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 1u, &meshStage, &nullShader); |
| } |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingMeshShaderBind) { |
| TEST_DESCRIPTION("Draw with shader objects without binding mesh shader."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08607"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08690"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_1, true, true)); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| { |
| VkShaderStageFlagBits taskStage = VK_SHADER_STAGE_TASK_BIT_EXT; |
| VkShaderEXT nullShader = VK_NULL_HANDLE; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 1u, &taskStage, &nullShader); |
| } |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, VertAndMeshShaderBothBound) { |
| TEST_DESCRIPTION("Draw with both vertex and mesh shader objects bound."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08693"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08696"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08885"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_3, true, true)); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| const vkt::Shader meshShader(*m_device, VK_SHADER_STAGE_MESH_BIT_EXT, |
| GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3), |
| VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| { |
| VkShaderStageFlagBits taskStage = VK_SHADER_STAGE_TASK_BIT_EXT; |
| VkShaderEXT nullShader = VK_NULL_HANDLE; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 1u, &taskStage, &nullShader); |
| } |
| VkShaderStageFlagBits meshStage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 1u, &meshStage, &meshShader.handle()); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MeshShaderWithMissingTaskShader) { |
| TEST_DESCRIPTION("Draw with a mesh shader that was created without the no task shader flag, but no task shader bound."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08694"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08885"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_3, true, true)); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| const vkt::Shader meshShader(*m_device, VK_SHADER_STAGE_MESH_BIT_EXT, |
| GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, |
| VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, VK_SHADER_STAGE_GEOMETRY_BIT, |
| VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const VkShaderEXT shaders[] = {VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, fragShader.handle()}; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 5u, stages, shaders); |
| |
| VkShaderStageFlagBits taskStage = VK_SHADER_STAGE_TASK_BIT_EXT; |
| VkShaderEXT nullShader = VK_NULL_HANDLE; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 1u, &taskStage, &nullShader); |
| VkShaderStageFlagBits meshStage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 1u, &meshStage, &meshShader.handle()); |
| |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, TaskAndMeshShaderWithNoTaskFlag) { |
| TEST_DESCRIPTION("Draw with a task and a mesh shader that was created with the no task shader flag."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08695"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08885"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_3, true, true)); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| const vkt::Shader taskShader(*m_device, VK_SHADER_STAGE_TASK_BIT_EXT, |
| GLSLToSPV(VK_SHADER_STAGE_TASK_BIT_EXT, kTaskMinimalGlsl, SPV_ENV_VULKAN_1_3)); |
| |
| const auto mesh_spv = GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| VkShaderCreateInfoEXT meshCreateInfo = vku::InitStructHelper(); |
| meshCreateInfo.flags = VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT; |
| meshCreateInfo.stage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| meshCreateInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| meshCreateInfo.codeSize = mesh_spv.size() * sizeof(mesh_spv[0]); |
| meshCreateInfo.pCode = mesh_spv.data(); |
| meshCreateInfo.pName = "main"; |
| const vkt::Shader meshShader(*m_device, meshCreateInfo); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, |
| VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, VK_SHADER_STAGE_GEOMETRY_BIT, |
| VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const VkShaderEXT shaders[] = {VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, fragShader.handle()}; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 5u, stages, shaders); |
| |
| VkShaderStageFlagBits taskStage = VK_SHADER_STAGE_TASK_BIT_EXT; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 1u, &taskStage, &taskShader.handle()); |
| VkShaderStageFlagBits meshStage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 1u, &meshStage, &meshShader.handle()); |
| |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, VertAndTaskShadersBound) { |
| TEST_DESCRIPTION("Draw with a vertex shader and task shaders bound as well."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08693"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08696"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08885"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_3, true, true)); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| const auto mesh_spv = GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| VkShaderCreateInfoEXT meshCreateInfo = vku::InitStructHelper(); |
| meshCreateInfo.flags = VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT; |
| meshCreateInfo.stage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| meshCreateInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| meshCreateInfo.codeSize = mesh_spv.size() * sizeof(mesh_spv[0]); |
| meshCreateInfo.pCode = mesh_spv.data(); |
| meshCreateInfo.pName = "main"; |
| const vkt::Shader meshShader(*m_device, meshCreateInfo); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, |
| VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, VK_SHADER_STAGE_GEOMETRY_BIT, |
| VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const VkShaderEXT shaders[] = {vertShader.handle(), VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, fragShader.handle()}; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 5u, stages, shaders); |
| |
| VkShaderStageFlagBits taskStage = VK_SHADER_STAGE_TASK_BIT_EXT; |
| VkShaderEXT nullShader = VK_NULL_HANDLE; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 1u, &taskStage, &nullShader); |
| VkShaderStageFlagBits meshStage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| { vk::CmdBindShadersEXT(m_commandBuffer->handle(), 1u, &meshStage, &meshShader.handle()); } |
| |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingLinkedShaderBind) { |
| TEST_DESCRIPTION("Draw with not all linked shaders bound."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08698"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const auto vert_spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| const auto frag_spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfos[2]; |
| createInfos[0] = vku::InitStructHelper(); |
| createInfos[0].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[0].stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfos[0].nextStage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfos[0].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[0].codeSize = vert_spv.size() * sizeof(vert_spv[0]); |
| createInfos[0].pCode = vert_spv.data(); |
| createInfos[0].pName = "main"; |
| |
| createInfos[1] = vku::InitStructHelper(); |
| createInfos[1].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfos[1].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[1].codeSize = frag_spv.size() * sizeof(frag_spv[0]); |
| createInfos[1].pCode = frag_spv.data(); |
| createInfos[1].pName = "main"; |
| |
| VkShaderEXT shaders[2]; |
| vk::CreateShadersEXT(*m_device, 2u, createInfos, nullptr, shaders); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, |
| VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, VK_SHADER_STAGE_GEOMETRY_BIT, |
| VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const VkShaderEXT bindShaders[] = {shaders[0], VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE}; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 5u, stages, bindShaders); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| for (uint32_t i = 0; i < 2; ++i) { |
| vk::DestroyShaderEXT(*m_device, shaders[i], nullptr); |
| } |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, BindShaderBetweenLinkedShaders) { |
| TEST_DESCRIPTION("Draw when a shader is bound between linked shaders."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08699"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const auto vert_spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| const auto frag_spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfos[2]; |
| createInfos[0] = vku::InitStructHelper(); |
| createInfos[0].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[0].stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfos[0].nextStage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfos[0].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[0].codeSize = vert_spv.size() * sizeof(vert_spv[0]); |
| createInfos[0].pCode = vert_spv.data(); |
| createInfos[0].pName = "main"; |
| |
| createInfos[1] = vku::InitStructHelper(); |
| createInfos[1].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfos[1].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[1].codeSize = frag_spv.size() * sizeof(frag_spv[0]); |
| createInfos[1].pCode = frag_spv.data(); |
| createInfos[1].pName = "main"; |
| |
| VkShaderEXT shaders[2]; |
| vk::CreateShadersEXT(*m_device, 2u, createInfos, nullptr, shaders); |
| |
| const vkt::Shader geomShader(*m_device, VK_SHADER_STAGE_GEOMETRY_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_GEOMETRY_BIT, kGeometryMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, |
| VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, VK_SHADER_STAGE_GEOMETRY_BIT, |
| VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const VkShaderEXT bindShaders[] = {shaders[0], VK_NULL_HANDLE, VK_NULL_HANDLE, geomShader.handle(), shaders[1]}; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 5u, stages, bindShaders); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| for (uint32_t i = 0; i < 2; ++i) { |
| vk::DestroyShaderEXT(*m_device, shaders[i], nullptr); |
| } |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, DifferentShaderPushConstantRanges) { |
| TEST_DESCRIPTION("Draw with shaders that have different push constant ranges."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08878"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| VkPushConstantRange pushConstRange; |
| pushConstRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; |
| pushConstRange.offset = 0u; |
| pushConstRange.size = sizeof(uint32_t); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl), |
| nullptr, &pushConstRange); |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, DifferentShaderDescriptorLayouts) { |
| TEST_DESCRIPTION("Draw with shaders that have different descriptor layouts."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08879"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| OneOffDescriptorSet descriptor_set(m_device, { |
| {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, |
| }); |
| vkt::PipelineLayout pipeline_layout(*m_device, {&descriptor_set.layout_}); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl), |
| &descriptor_set.layout_.handle(), nullptr); |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0u, 1u, |
| &descriptor_set.set_, 0u, nullptr); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetAttachmentFeedbackLoopEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetAttachmentFeedbackLoopEnableEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08880"); |
| |
| AddRequiredExtensions(VK_EXT_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::attachmentFeedbackLoopDynamicState); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetPrimitiveTopologyEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetPrimitiveTopologyEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-07842"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetPatchControlPointsEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetPatchControlPointsEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-04875"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| VkPhysicalDeviceFeatures features; |
| GetPhysicalDeviceFeatures(&features); |
| if (features.tessellationShader == VK_FALSE) { |
| GTEST_SKIP() << "tessellationShader not supported."; |
| } |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| const vkt::Shader tescShader(*m_device, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, kTessellationControlMinimalGlsl)); |
| const vkt::Shader teseShader(*m_device, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, kTessellationEvalMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT}); |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, |
| VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, VK_SHADER_STAGE_GEOMETRY_BIT, |
| VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const VkShaderEXT shaders[] = {vertShader.handle(), tescShader.handle(), teseShader.handle(), VK_NULL_HANDLE, |
| fragShader.handle()}; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 5u, stages, shaders); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetTessellationDomainOriginEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetTessellationDomainOriginEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-09237"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| VkPhysicalDeviceFeatures features; |
| GetPhysicalDeviceFeatures(&features); |
| if (features.tessellationShader == VK_FALSE) { |
| GTEST_SKIP() << "tessellationShader not supported."; |
| } |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| const vkt::Shader tescShader(*m_device, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, kTessellationControlMinimalGlsl)); |
| const vkt::Shader teseShader(*m_device, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, kTessellationEvalMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT}); |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, |
| VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, VK_SHADER_STAGE_GEOMETRY_BIT, |
| VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const VkShaderEXT shaders[] = {vertShader.handle(), tescShader.handle(), teseShader.handle(), VK_NULL_HANDLE, |
| fragShader.handle()}; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 5u, stages, shaders); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetPrimitiveRestartEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetPrimitiveRestartEnableEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-04879"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, DrawWithGraphicsShadersWhenMeshShaderIsBound) { |
| TEST_DESCRIPTION("Draw with graphics shader objects when a mesh shader is bound."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08885"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_3, true, true)); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| const vkt::Shader meshShader(*m_device, VK_SHADER_STAGE_MESH_BIT_EXT, |
| GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3), |
| VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, |
| VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, VK_SHADER_STAGE_GEOMETRY_BIT, |
| VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const VkShaderEXT shaders[] = {VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, fragShader.handle()}; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 5u, stages, shaders); |
| { |
| VkShaderStageFlagBits taskStage = VK_SHADER_STAGE_TASK_BIT_EXT; |
| VkShaderEXT nullShader = VK_NULL_HANDLE; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 1u, &taskStage, &nullShader); |
| } |
| VkShaderStageFlagBits meshStage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 1u, &meshStage, &meshShader.handle()); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingPolygonLineCmdSetLineWidthEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetLineWidthEXT when polygon mode is line."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08617"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_LINE_WIDTH}); |
| vk::CmdSetPolygonModeEXT(m_commandBuffer->handle(), VK_POLYGON_MODE_LINE); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingPrimitiveTopologyLineCmdSetLineWidthEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetLineWidthEXT when primitive topology is line."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08618"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_LINE_WIDTH}); |
| vk::CmdSetPrimitiveTopologyEXT(m_commandBuffer->handle(), VK_PRIMITIVE_TOPOLOGY_LINE_LIST); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthBiasEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDepthBiasEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08620"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_DEPTH_BIAS}); |
| vk::CmdSetDepthBiasEnableEXT(m_commandBuffer->handle(), VK_TRUE); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetBlendConstantsEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetBlendConstantsEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08621"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_BLEND_CONSTANTS}); |
| VkColorBlendEquationEXT colorBlendEquation = { |
| VK_BLEND_FACTOR_CONSTANT_COLOR, |
| VK_BLEND_FACTOR_ONE, |
| VK_BLEND_OP_ADD, |
| VK_BLEND_FACTOR_ONE, |
| VK_BLEND_FACTOR_ONE, |
| VK_BLEND_OP_ADD, |
| }; |
| vk::CmdSetColorBlendEquationEXT(m_commandBuffer->handle(), 0u, 1u, &colorBlendEquation); |
| BindVertFragShader(vertShader, fragShader); |
| VkBool32 colorBlendEnable = VK_TRUE; |
| vk::CmdSetColorBlendEnableEXT(m_commandBuffer->handle(), 0u, 1u, &colorBlendEnable); |
| VkColorBlendAdvancedEXT colorBlendAdvanced; |
| colorBlendAdvanced.advancedBlendOp = VK_BLEND_OP_ADD; |
| colorBlendAdvanced.srcPremultiplied = VK_FALSE; |
| colorBlendAdvanced.dstPremultiplied = VK_FALSE; |
| colorBlendAdvanced.blendOverlap = VK_BLEND_OVERLAP_UNCORRELATED_EXT; |
| colorBlendAdvanced.clampResults = VK_FALSE; |
| vk::CmdSetColorBlendAdvancedEXT(m_commandBuffer->handle(), 0u, 1u, &colorBlendAdvanced); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthBoundsEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDepthBoundsEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08622"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_DEPTH_BOUNDS}); |
| vk::CmdSetDepthBoundsTestEnableEXT(m_commandBuffer->handle(), VK_TRUE); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetStencilCompareMaskEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetStencilCompareMaskEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08623"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK}); |
| vk::CmdSetStencilTestEnableEXT(m_commandBuffer->handle(), VK_TRUE); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetStencilWriteMaskEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetStencilWriteMaskEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08624"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_STENCIL_WRITE_MASK}); |
| vk::CmdSetStencilTestEnableEXT(m_commandBuffer->handle(), VK_TRUE); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetStencilReferenceEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetStencilReferenceEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08625"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_STENCIL_REFERENCE}); |
| vk::CmdSetStencilTestEnableEXT(m_commandBuffer->handle(), VK_TRUE); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetSampleLocationsEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetSampleLocationsEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08626"); |
| |
| AddRequiredExtensions(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT}); |
| vk::CmdSetSampleLocationsEnableEXT(m_commandBuffer->handle(), VK_TRUE); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetCullModeEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetCullModeEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08627"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_CULL_MODE_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetFrontFaceEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetFrontFaceEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08628"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_FRONT_FACE_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdSetCullModeEXT(m_commandBuffer->handle(), VK_CULL_MODE_BACK_BIT); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthTestEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDepthTestEnableEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08629"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthWriteEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDepthWriteEnableEXT."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08630"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthCompareOp) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDepthCompareOp."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08631"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT}); |
| vk::CmdSetDepthTestEnableEXT(m_commandBuffer->handle(), VK_TRUE); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthBoundsTestEnable) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDepthBoundsTestEnable."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08632"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| VkPhysicalDeviceFeatures features; |
| GetPhysicalDeviceFeatures(&features); |
| if (features.depthBounds == VK_FALSE) { |
| GTEST_SKIP() << "depthBounds not supported."; |
| } |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetStencilTestEnable) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetStencilTestEnable."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08633"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| VkPhysicalDeviceFeatures features; |
| GetPhysicalDeviceFeatures(&features); |
| if (features.depthBounds == VK_FALSE) { |
| GTEST_SKIP() << "depthBounds not supported."; |
| } |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetStencilOp) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetStencilOp."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08634"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| VkPhysicalDeviceFeatures features; |
| GetPhysicalDeviceFeatures(&features); |
| if (features.depthBounds == VK_FALSE) { |
| GTEST_SKIP() << "depthBounds not supported."; |
| } |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_STENCIL_OP_EXT}); |
| vk::CmdSetStencilTestEnableEXT(m_commandBuffer->handle(), VK_TRUE); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, ComputeShaderGroupCount) { |
| TEST_DESCRIPTION("Dispatch with group count higher than maxComputeWorkGroupCount."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| uint32_t x_count_limit = m_device->phy().limits_.maxComputeWorkGroupCount[0]; |
| uint32_t y_count_limit = m_device->phy().limits_.maxComputeWorkGroupCount[1]; |
| uint32_t z_count_limit = m_device->phy().limits_.maxComputeWorkGroupCount[2]; |
| |
| const vkt::Shader compShader(*m_device, VK_SHADER_STAGE_COMPUTE_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, kMinimalShaderGlsl)); |
| |
| m_commandBuffer->begin(); |
| |
| BindCompShader(compShader); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDispatch-groupCountX-00386"); |
| vk::CmdDispatch(m_commandBuffer->handle(), x_count_limit + 1u, 1u, 1u); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDispatch-groupCountY-00387"); |
| vk::CmdDispatch(m_commandBuffer->handle(), 1u, y_count_limit + 1u, 1u); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDispatch-groupCountZ-00388"); |
| vk::CmdDispatch(m_commandBuffer->handle(), 1u, 1u, z_count_limit + 1u); |
| m_errorMonitor->VerifyFound(); |
| |
| m_commandBuffer->end(); |
| } |
| |
| TEST_F(NegativeShaderObject, ComputeShaderMissingPushConst) { |
| TEST_DESCRIPTION("Dispatch with a shader object using push const, but not setting it."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDispatch-maintenance4-08602"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| VkPushConstantRange pushConstRange; |
| pushConstRange.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; |
| pushConstRange.offset = 0u; |
| pushConstRange.size = sizeof(int); |
| |
| static const char kComputeShaderGlsl[] = R"glsl( |
| #version 460 |
| layout (push_constant) uniform constants { |
| int value; |
| } PushConstants; |
| layout(set = 0, binding = 0) buffer foo { |
| int x; |
| } bar; |
| void main() { |
| bar.x = PushConstants.value; |
| } |
| )glsl"; |
| |
| OneOffDescriptorSet descriptor_set(m_device, |
| { |
| {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, |
| }); |
| |
| vkt::PipelineLayout pipeline_layout(*m_device, {&descriptor_set.layout_}, {pushConstRange}); |
| |
| const vkt::Shader compShader(*m_device, VK_SHADER_STAGE_COMPUTE_BIT, GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, kComputeShaderGlsl), |
| &descriptor_set.layout_.handle(), &pushConstRange); |
| |
| vkt::Buffer buffer(*m_device, 32, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| descriptor_set.WriteDescriptorBufferInfo(0, buffer.handle(), 0, 32, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); |
| descriptor_set.UpdateDescriptorSets(); |
| |
| m_commandBuffer->begin(); |
| vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_layout.handle(), 0u, 1u, |
| &descriptor_set.set_, 0u, nullptr); |
| BindCompShader(compShader); |
| vk::CmdDispatch(m_commandBuffer->handle(), 1u, 1u, 1u); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, SharedMemoryOverLimit) { |
| TEST_DESCRIPTION("Validate compute shader shared memory does not exceed maxComputeSharedMemorySize"); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-Workgroup-06530"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const uint32_t max_shared_memory_size = m_device->phy().limits_.maxComputeSharedMemorySize; |
| const uint32_t max_shared_ints = max_shared_memory_size / 4; |
| |
| std::stringstream csSource; |
| // Make sure compute pipeline has a compute shader stage set |
| csSource << R"glsl( |
| #version 450 |
| shared int a[)glsl"; |
| csSource << (max_shared_ints + 16); |
| csSource << R"glsl(]; |
| void main(){ |
| } |
| )glsl"; |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, csSource.str().c_str()); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidRequireFullSubgroupsFlag) { |
| TEST_DESCRIPTION("Create shader with invalid spirv code size."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-flags-08992"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.flags = VK_SHADER_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT; |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, SpecializationMapEntryOffset) { |
| TEST_DESCRIPTION("Create shader with invalid specialization map entry offset."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSpecializationInfo-offset-00773"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| static const char kVertexSource[] = R"glsl( |
| #version 460 |
| layout (constant_id = 0) const int v = 0; |
| void main() { |
| gl_Position = vec4(v); |
| } |
| )glsl"; |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexSource); |
| |
| int data = 0; |
| |
| VkSpecializationMapEntry mapEntry = {}; |
| mapEntry.constantID = 0u; |
| mapEntry.offset = sizeof(int) * 2; |
| mapEntry.size = sizeof(int); |
| |
| VkSpecializationInfo specializationInfo = {}; |
| specializationInfo.mapEntryCount = 1; |
| specializationInfo.pMapEntries = &mapEntry; |
| specializationInfo.dataSize = sizeof(uint32_t); |
| specializationInfo.pData = &data; |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| createInfo.pSpecializationInfo = &specializationInfo; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, SpecializationMapEntrySize) { |
| TEST_DESCRIPTION("Create shader with specialization map entry out of bounds."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSpecializationInfo-pMapEntries-00774"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| static const char kVertexSource[] = R"glsl( |
| #version 460 |
| layout (constant_id = 0) const int v = 0; |
| void main() { |
| gl_Position = vec4(v); |
| } |
| )glsl"; |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexSource); |
| |
| int data = 0; |
| |
| VkSpecializationMapEntry mapEntry = {}; |
| mapEntry.constantID = 0u; |
| mapEntry.offset = sizeof(int) / 2; |
| mapEntry.size = sizeof(int); |
| |
| VkSpecializationInfo specializationInfo = {}; |
| specializationInfo.mapEntryCount = 1; |
| specializationInfo.pMapEntries = &mapEntry; |
| specializationInfo.dataSize = sizeof(uint32_t); |
| specializationInfo.pData = &data; |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| createInfo.pSpecializationInfo = &specializationInfo; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, SpecializationMismatch) { |
| TEST_DESCRIPTION("Create shader with invalid spirv code size."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSpecializationMapEntry-constantID-00776"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| static const char kVertexSource[] = R"glsl( |
| #version 460 |
| layout (constant_id = 0) const int v = 0; |
| void main() { |
| gl_Position = vec4(v); |
| } |
| )glsl"; |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexSource); |
| |
| int data[2] = {0u, 0u}; |
| |
| VkSpecializationMapEntry mapEntry = {}; |
| mapEntry.constantID = 0u; |
| mapEntry.offset = 0u; |
| mapEntry.size = sizeof(int) * 2u; |
| |
| VkSpecializationInfo specializationInfo = {}; |
| specializationInfo.mapEntryCount = 1; |
| specializationInfo.pMapEntries = &mapEntry; |
| specializationInfo.dataSize = sizeof(uint32_t) * 2; |
| specializationInfo.pData = &data; |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| createInfo.pSpecializationInfo = &specializationInfo; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, SpecializationSameConstantId) { |
| TEST_DESCRIPTION("Create shader with non unique specialization map entries."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSpecializationInfo-constantID-04911"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| static const char kVertexSource[] = R"glsl( |
| #version 460 |
| layout (constant_id = 0) const int v = 0; |
| void main() { |
| gl_Position = vec4(v); |
| } |
| )glsl"; |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexSource); |
| |
| int data = 0; |
| |
| VkSpecializationMapEntry mapEntries[2] = {}; |
| mapEntries[0].constantID = 0u; |
| mapEntries[0].offset = 0u; |
| mapEntries[0].size = sizeof(int); |
| mapEntries[1].constantID = 0u; |
| mapEntries[1].offset = 0u; |
| mapEntries[1].size = sizeof(int); |
| |
| VkSpecializationInfo specializationInfo = {}; |
| specializationInfo.mapEntryCount = 2; |
| specializationInfo.pMapEntries = mapEntries; |
| specializationInfo.dataSize = sizeof(uint32_t); |
| specializationInfo.pData = &data; |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| createInfo.pSpecializationInfo = &specializationInfo; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingEntrypoint) { |
| TEST_DESCRIPTION("Create shader with invalid spirv code size."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-pName-08440"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "invalid"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, SpecializationApplied) { |
| TEST_DESCRIPTION( |
| "Make sure specialization constants get applied during shader validation by using a value that breaks compilation."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-pCode-08460"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| // Size an array using a specialization constant of default value equal to 1. |
| const char* fs_src = R"( |
| OpCapability Shader |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint Fragment %main "main" |
| OpExecutionMode %main OriginUpperLeft |
| OpSource GLSL 450 |
| OpName %main "main" |
| OpName %size "size" |
| OpName %array "array" |
| OpDecorate %size SpecId 0 |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %int = OpTypeInt 32 1 |
| %size = OpSpecConstant %int 1 |
| %_arr_float_size = OpTypeArray %float %size |
| %_ptr_Function__arr_float_size = OpTypePointer Function %_arr_float_size |
| %int_0 = OpConstant %int 0 |
| %float_0 = OpConstant %float 0 |
| %_ptr_Function_float = OpTypePointer Function %float |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %array = OpVariable %_ptr_Function__arr_float_size Function |
| %15 = OpAccessChain %_ptr_Function_float %array %int_0 |
| OpStore %15 %float_0 |
| OpReturn |
| OpFunctionEnd)"; |
| |
| std::vector<uint32_t> fs_spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, fs_src, fs_spv); |
| |
| uint32_t data = 0u; |
| |
| VkSpecializationMapEntry mapEntry = {}; |
| mapEntry.constantID = 0u; |
| mapEntry.offset = 0u; |
| mapEntry.size = sizeof(uint32_t); |
| |
| VkSpecializationInfo specializationInfo = {}; |
| specializationInfo.mapEntryCount = 1; |
| specializationInfo.pMapEntries = &mapEntry; |
| specializationInfo.dataSize = sizeof(uint32_t); |
| specializationInfo.pData = &data; |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = fs_spv.size() * sizeof(fs_spv[0]); |
| createInfo.pCode = fs_spv.data(); |
| createInfo.pName = "main"; |
| createInfo.pSpecializationInfo = &specializationInfo; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MinTexelGatherOffset) { |
| TEST_DESCRIPTION("Create shader with texel gather offset lower than minimum."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-OpImage-06376"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-OpImage-06377"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-OpImage-06377"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| // Size an array using a specialization constant of default value equal to 1. |
| const char* cs_src = R"( |
| OpCapability Shader |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %main "main" |
| OpExecutionMode %main LocalSize 1 1 1 |
| OpSource GLSL 450 |
| |
| ; Annotations |
| OpDecorate %samp DescriptorSet 0 |
| OpDecorate %samp Binding 0 |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %v4float = OpTypeVector %float 4 |
| %_ptr_Function_v4float = OpTypePointer Function %v4float |
| %10 = OpTypeImage %float 2D 0 0 0 1 Unknown |
| %11 = OpTypeSampledImage %10 |
| %_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11 |
| %samp = OpVariable %_ptr_UniformConstant_11 UniformConstant |
| %v2float = OpTypeVector %float 2 |
| %float_0_5 = OpConstant %float 0.5 |
| %17 = OpConstantComposite %v2float %float_0_5 %float_0_5 |
| ; set up composite to be validated |
| %uint = OpTypeInt 32 0 |
| %int = OpTypeInt 32 1 |
| %v2uint = OpTypeVector %uint 2 |
| %v2int = OpTypeVector %int 2 |
| %int_n100 = OpConstant %int -100 |
| %uint_n100 = OpConstant %uint 4294967196 |
| %int_100 = OpConstant %int 100 |
| %uint_0 = OpConstant %uint 0 |
| %int_0 = OpConstant %int 0 |
| %offset_100 = OpConstantComposite %v2int %int_n100 %int_100 |
| %offset_n100 = OpConstantComposite %v2uint %uint_0 %uint_n100 |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %color = OpVariable %_ptr_Function_v4float Function |
| %14 = OpLoad %11 %samp |
| ; Should trigger min and max |
| %24 = OpImageGather %v4float %14 %17 %int_0 ConstOffset %offset_100 |
| ; Should only trigger max since uint |
| %25 = OpImageGather %v4float %14 %17 %int_0 ConstOffset %offset_n100 |
| OpStore %color %24 |
| OpReturn |
| OpFunctionEnd)"; |
| |
| std::vector<uint32_t> cs_spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, cs_src, cs_spv); |
| |
| OneOffDescriptorSet descriptor_set(m_device, |
| { |
| {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, |
| }); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = cs_spv.size() * sizeof(cs_spv[0]); |
| createInfo.pCode = cs_spv.data(); |
| createInfo.pName = "main"; |
| createInfo.setLayoutCount = 1u; |
| createInfo.pSetLayouts = &descriptor_set.layout_.handle(); |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, UnsupportedSpirvCapability) { |
| TEST_DESCRIPTION("Create shader with unsupported spirv capability."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-pCode-08740"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_0); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::shaderObject); |
| AddDisabledFeature(vkt::Feature::shaderClipDistance); |
| RETURN_IF_SKIP(Init()); |
| |
| const char* vs_src = R"( |
| OpCapability Shader |
| OpCapability ClipDistance |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint Vertex %main "main" %_ |
| |
| ; Debug Information |
| OpSource GLSL 460 |
| OpName %main "main" ; id %4 |
| OpName %gl_PerVertex "gl_PerVertex" ; id %11 |
| OpMemberName %gl_PerVertex 0 "gl_Position" |
| OpMemberName %gl_PerVertex 1 "gl_PointSize" |
| OpMemberName %gl_PerVertex 2 "gl_ClipDistance" |
| OpMemberName %gl_PerVertex 3 "gl_CullDistance" |
| OpName %_ "" ; id %13 |
| |
| ; Annotations |
| OpMemberDecorate %gl_PerVertex 0 BuiltIn Position |
| OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize |
| OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance |
| OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance |
| OpDecorate %gl_PerVertex Block |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %v4float = OpTypeVector %float 4 |
| %uint = OpTypeInt 32 0 |
| %uint_1 = OpConstant %uint 1 |
| %_arr_float_uint_1 = OpTypeArray %float %uint_1 |
| %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 |
| %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex |
| %_ = OpVariable %_ptr_Output_gl_PerVertex Output |
| %int = OpTypeInt 32 1 |
| %int_0 = OpConstant %int 0 |
| %float_1 = OpConstant %float 1 |
| %17 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 |
| %_ptr_Output_v4float = OpTypePointer Output %v4float |
| %int_2 = OpConstant %int 2 |
| %_ptr_Output_float = OpTypePointer Output %float |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %19 = OpAccessChain %_ptr_Output_v4float %_ %int_0 |
| OpStore %19 %17 |
| %22 = OpAccessChain %_ptr_Output_float %_ %int_2 %int_0 |
| OpStore %22 %float_1 |
| OpReturn |
| OpFunctionEnd)"; |
| |
| std::vector<uint32_t> vs_spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, vs_src, vs_spv); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = vs_spv.size() * sizeof(vs_spv[0]); |
| createInfo.pCode = vs_spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, UnsupportedSpirvExtension) { |
| TEST_DESCRIPTION("Create shader with unsupported spirv extension."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-pCode-08741"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_0); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::shaderObject); |
| RETURN_IF_SKIP(Init()); |
| |
| const char* vs_src = R"( |
| OpCapability Shader |
| OpExtension "GL_EXT_scalar_block_layout" |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint Vertex %4 "main" |
| OpSource GLSL 450 |
| OpName %4 "main" |
| %2 = OpTypeVoid |
| %3 = OpTypeFunction %2 |
| %4 = OpFunction %2 None %3 |
| %5 = OpLabel |
| OpReturn |
| OpFunctionEnd)"; |
| |
| std::vector<uint32_t> vs_spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, vs_src, vs_spv); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = vs_spv.size() * sizeof(vs_spv[0]); |
| createInfo.pCode = vs_spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, SpirvExtensionRequirementsNotMet) { |
| TEST_DESCRIPTION("Create shader with extension requirements not met."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-pCode-08742"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_0); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::shaderObject); |
| RETURN_IF_SKIP(Init()); |
| |
| const char* cs_src = R"( |
| OpCapability Shader |
| OpExtension "SPV_KHR_non_semantic_info" |
| %non_semantic = OpExtInstImport "NonSemantic.Validation.Test" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %main "main" |
| OpExecutionMode %main LocalSize 1 1 1 |
| %void = OpTypeVoid |
| %1 = OpExtInst %void %non_semantic 55 %void |
| %func = OpTypeFunction %void |
| %main = OpFunction %void None %func |
| %2 = OpLabel |
| OpReturn |
| OpFunctionEnd)"; |
| |
| std::vector<uint32_t> cs_spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, cs_src, cs_spv); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = cs_spv.size() * sizeof(cs_spv[0]); |
| createInfo.pCode = cs_spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MemoryModelNotEnabled) { |
| TEST_DESCRIPTION("Create shader with unsupported spirv extension."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-vulkanMemoryModel-06265"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| |
| RETURN_IF_SKIP(InitFramework()); |
| VkPhysicalDeviceShaderObjectFeaturesEXT shaderObjectFeatures = vku::InitStructHelper(); |
| VkPhysicalDeviceVulkan12Features features12 = vku::InitStructHelper(&shaderObjectFeatures); |
| auto features2 = GetPhysicalDeviceFeatures2(features12); |
| features12.vulkanMemoryModelDeviceScope = VK_FALSE; |
| if (features12.vulkanMemoryModel == VK_FALSE) { |
| GTEST_SKIP() << "vulkanMemoryModel feature is not supported"; |
| } |
| RETURN_IF_SKIP(InitState(nullptr, &features2)); |
| |
| char const* cs_src = R"glsl( |
| #version 450 |
| #extension GL_KHR_memory_scope_semantics : enable |
| layout(set = 0, binding = 0) buffer ssbo { uint y; }; |
| void main() { |
| atomicStore(y, 1u, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelaxed); |
| } |
| )glsl"; |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, cs_src); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MaxTransformFeedbackStream) { |
| TEST_DESCRIPTION("Test maxTransformFeedbackStream with shader objects."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-OpEmitStreamVertex-06310"); |
| |
| AddRequiredExtensions(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::geometryShader); |
| AddRequiredFeature(vkt::Feature::transformFeedback); |
| AddRequiredFeature(vkt::Feature::geometryStreams); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| VkPhysicalDeviceTransformFeedbackPropertiesEXT transform_feedback_props = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(transform_feedback_props); |
| |
| // seen sometimes when using profiles and will crash |
| if (transform_feedback_props.maxTransformFeedbackStreams == 0) { |
| GTEST_SKIP() << "maxTransformFeedbackStreams is zero"; |
| } |
| |
| std::stringstream gsSource; |
| gsSource << R"asm( |
| OpCapability Geometry |
| OpCapability TransformFeedback |
| OpCapability GeometryStreams |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint Geometry %main "main" %tf |
| OpExecutionMode %main Xfb |
| OpExecutionMode %main Triangles |
| OpExecutionMode %main Invocations 1 |
| OpExecutionMode %main OutputTriangleStrip |
| OpExecutionMode %main OutputVertices 1 |
| |
| ; Debug Information |
| OpSource GLSL 450 |
| OpName %main "main" ; id %4 |
| OpName %tf "tf" ; id %10 |
| |
| ; Annotations |
| OpDecorate %tf Location 0 |
| OpDecorate %tf Stream 0 |
| OpDecorate %tf XfbBuffer 0 |
| OpDecorate %tf XfbStride 0 |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %int = OpTypeInt 32 1 |
| %int_17 = OpConstant %int )asm"; |
| gsSource << transform_feedback_props.maxTransformFeedbackStreams; |
| gsSource << R"asm( |
| %float = OpTypeFloat 32 |
| %_ptr_Output_float = OpTypePointer Output %float |
| %tf = OpVariable %_ptr_Output_float Output |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| OpEmitStreamVertex %int_17 |
| OpReturn |
| OpFunctionEnd |
| )asm"; |
| |
| std::vector<uint32_t> gs_spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, gsSource.str().c_str(), gs_spv); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_GEOMETRY_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = gs_spv.size() * sizeof(gs_spv[0]); |
| createInfo.pCode = gs_spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, TransformFeedbackStride) { |
| TEST_DESCRIPTION("Test maxTransformFeedbackStream with shader objects."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-XfbStride-06313"); |
| |
| AddRequiredExtensions(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::geometryShader); |
| AddRequiredFeature(vkt::Feature::transformFeedback); |
| AddRequiredFeature(vkt::Feature::geometryStreams); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| VkPhysicalDeviceTransformFeedbackPropertiesEXT transform_feedback_props = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(transform_feedback_props); |
| |
| // seen sometimes when using profiles and will crash |
| if (transform_feedback_props.maxTransformFeedbackStreams == 0) { |
| GTEST_SKIP() << "maxTransformFeedbackStreams is zero"; |
| } |
| |
| std::stringstream vsSource; |
| vsSource << R"asm( |
| OpCapability Shader |
| OpCapability TransformFeedback |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint Vertex %main "main" %tf |
| OpExecutionMode %main Xfb |
| |
| ; Debug Information |
| OpSource GLSL 450 |
| OpName %main "main" ; id %4 |
| OpName %tf "tf" ; id %8 |
| |
| ; Annotations |
| OpDecorate %tf Location 0 |
| OpDecorate %tf XfbBuffer 0 |
| OpDecorate %tf XfbStride )asm"; |
| vsSource << transform_feedback_props.maxTransformFeedbackBufferDataStride + 4; |
| vsSource << R"asm( |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %_ptr_Output_float = OpTypePointer Output %float |
| %tf = OpVariable %_ptr_Output_float Output |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| OpReturn |
| OpFunctionEnd |
| )asm"; |
| |
| std::vector<uint32_t> vs_spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, vsSource.str().c_str(), vs_spv); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = vs_spv.size() * sizeof(vs_spv[0]); |
| createInfo.pCode = vs_spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MeshOutputVertices) { |
| TEST_DESCRIPTION("Create mesh shader with output vertices higher than max."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-MeshEXT-07115"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(nullptr, VK_API_VERSION_1_3, false, true)); |
| |
| VkPhysicalDeviceMeshShaderPropertiesEXT mesh_shader_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(mesh_shader_properties); |
| |
| std::string mesh_src = R"( |
| OpCapability MeshShadingEXT |
| OpExtension "SPV_EXT_mesh_shader" |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint MeshEXT %main "main" |
| OpExecutionMode %main LocalSize 1 1 1 |
| OpExecutionMode %main OutputVertices )"; |
| mesh_src += std::to_string(mesh_shader_properties.maxMeshOutputVertices + 1); |
| mesh_src += R"( |
| OpExecutionMode %main OutputPrimitivesEXT 1 |
| OpExecutionMode %main OutputTrianglesEXT |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %uint = OpTypeInt 32 0 |
| %uint_1 = OpConstant %uint 1 |
| %v3uint = OpTypeVector %uint 3 |
| %9 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| OpReturn |
| OpFunctionEnd |
| )"; |
| |
| std::vector<uint32_t> spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_3, 0, mesh_src.c_str(), spv); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| createInfo.nextStage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, Atomics) { |
| TEST_DESCRIPTION("Test atomics with shader objects."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-pCode-08740"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-None-06278"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| VkPhysicalDeviceFeatures available_features = {}; |
| GetPhysicalDeviceFeatures(&available_features); |
| if (!available_features.shaderInt64) { |
| GTEST_SKIP() << "shaderInt64 is not supported"; |
| } |
| |
| std::string cs_src = R"glsl( |
| #version 450 |
| #extension GL_EXT_shader_explicit_arithmetic_types_int64 : enable |
| #extension GL_EXT_shader_atomic_int64 : enable |
| #extension GL_KHR_memory_scope_semantics : enable |
| shared uint64_t x; |
| layout(set = 0, binding = 0) buffer ssbo { uint64_t y; }; |
| void main() { |
| atomicAdd(y, 1); |
| } |
| )glsl"; |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, cs_src.c_str()); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, ExtendedTypesDisabled) { |
| TEST_DESCRIPTION("Test VK_KHR_shader_subgroup_extended_types."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-None-06275"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_4_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::shaderObject); |
| AddRequiredFeature(vkt::Feature::maintenance4); |
| AddRequiredFeature(vkt::Feature::shaderFloat16); |
| AddDisabledFeature(vkt::Feature::shaderSubgroupExtendedTypes); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceSubgroupProperties subgroup_prop = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(subgroup_prop); |
| if (!(subgroup_prop.supportedOperations & VK_SUBGROUP_FEATURE_ARITHMETIC_BIT) || |
| !(subgroup_prop.supportedStages & VK_SHADER_STAGE_COMPUTE_BIT)) { |
| GTEST_SKIP() << "Required features not supported"; |
| } |
| |
| char const* cs_src = R"glsl( |
| #version 450 |
| #extension GL_KHR_shader_subgroup_arithmetic : enable |
| #extension GL_EXT_shader_subgroup_extended_types_float16 : enable |
| #extension GL_EXT_shader_explicit_arithmetic_types_float16 : enable |
| layout(local_size_x = 32) in; |
| void main() { |
| subgroupAdd(float16_t(0.0)); |
| } |
| )glsl"; |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, cs_src, SPV_ENV_VULKAN_1_3); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, ReadShaderClock) { |
| TEST_DESCRIPTION("Test VK_KHR_shader_clock"); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-shaderSubgroupClock-06267"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_KHR_SHADER_CLOCK_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| char const* vs_src = R"glsl( |
| #version 450 |
| #extension GL_ARB_shader_clock: enable |
| void main(){ |
| uvec2 a = clock2x32ARB(); |
| gl_Position = vec4(float(a.x) * 0.0); |
| } |
| )glsl"; |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, vs_src, SPV_ENV_VULKAN_1_3); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, WriteLessComponent) { |
| TEST_DESCRIPTION("Test writing to image with less components."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-OpImageWrite-07112"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* cs_src = R"( |
| OpCapability Shader |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %main "main" %var |
| OpExecutionMode %main LocalSize 1 1 1 |
| OpDecorate %var DescriptorSet 0 |
| OpDecorate %var Binding 0 |
| %void = OpTypeVoid |
| %func = OpTypeFunction %void |
| %int = OpTypeInt 32 1 |
| %uint = OpTypeInt 32 0 |
| %image = OpTypeImage %uint 2D 0 0 0 2 Rgba8ui |
| %ptr = OpTypePointer UniformConstant %image |
| %var = OpVariable %ptr UniformConstant |
| %v2int = OpTypeVector %int 2 |
| %int_1 = OpConstant %int 1 |
| %coord = OpConstantComposite %v2int %int_1 %int_1 |
| %v3uint = OpTypeVector %uint 3 |
| %uint_1 = OpConstant %uint 1 |
| %texelU3 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 |
| %main = OpFunction %void None %func |
| %label = OpLabel |
| %load = OpLoad %image %var |
| OpImageWrite %load %coord %texelU3 ZeroExtend |
| OpReturn |
| OpFunctionEnd |
| )"; |
| |
| std::vector<uint32_t> spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_3, 0, cs_src, spv); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, LocalSizeIdExecutionMode) { |
| TEST_DESCRIPTION("Test LocalSizeId spirv execution mode."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-LocalSizeId-06434"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_4_EXTENSION_NAME); |
| AddDisabledFeature(vkt::Feature::maintenance4); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* cs_src = R"( |
| OpCapability Shader |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %main "main" |
| OpExecutionModeId %main LocalSizeId %uint_1 %uint_1 %uint_1 |
| OpSource GLSL 450 |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %uint = OpTypeInt 32 0 |
| %uint_1 = OpConstant %uint 1 |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| OpReturn |
| OpFunctionEnd |
| )"; |
| |
| std::vector<uint32_t> spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_3, 0, cs_src, spv); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, ZeroInitializeWorkgroupMemory) { |
| TEST_DESCRIPTION("Test initializing workgroup memory in compute shader."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-shaderZeroInitializeWorkgroupMemory-06372"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* cs_src = R"( |
| OpCapability Shader |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %main "main" |
| OpExecutionMode %main LocalSize 1 1 1 |
| OpSource GLSL 450 |
| OpName %main "main" |
| OpName %counter "counter" |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %uint = OpTypeInt 32 0 |
| %_ptr_Workgroup_uint = OpTypePointer Workgroup %uint |
| %zero_uint = OpConstantNull %uint |
| %counter = OpVariable %_ptr_Workgroup_uint Workgroup %zero_uint |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| OpReturn |
| OpFunctionEnd |
| )"; |
| |
| std::vector<uint32_t> spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_2, 0, cs_src, spv); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingNonReadableDecorationFormatRead) { |
| TEST_DESCRIPTION("Create a shader with a storage image without an image format not marked as non readable."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-apiVersion-07954"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-apiVersion-07955"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME)) { |
| GTEST_SKIP() << "VK_KHR_format_feature_flags2 is supported"; |
| } |
| |
| const char* cs_src = R"( |
| OpCapability Shader |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %4 "main" |
| OpExecutionMode %4 LocalSize 1 1 1 |
| OpSource GLSL 450 |
| OpName %4 "main" |
| OpName %9 "value" |
| OpName %12 "img" |
| OpDecorate %12 DescriptorSet 0 |
| OpDecorate %12 Binding 0 |
| OpDecorate %22 BuiltIn WorkgroupSize |
| %2 = OpTypeVoid |
| %3 = OpTypeFunction %2 |
| %6 = OpTypeFloat 32 |
| %7 = OpTypeVector %6 4 |
| %8 = OpTypePointer Function %7 |
| %10 = OpTypeImage %6 2D 0 0 0 2 Unknown |
| %11 = OpTypePointer UniformConstant %10 |
| %12 = OpVariable %11 UniformConstant |
| %14 = OpTypeInt 32 1 |
| %15 = OpTypeVector %14 2 |
| %16 = OpConstant %14 0 |
| %17 = OpConstantComposite %15 %16 %16 |
| %19 = OpTypeInt 32 0 |
| %20 = OpTypeVector %19 3 |
| %21 = OpConstant %19 1 |
| %22 = OpConstantComposite %20 %21 %21 %21 |
| %4 = OpFunction %2 None %3 |
| %l = OpLabel |
| %9 = OpVariable %8 Function |
| OpReturn |
| OpFunctionEnd |
| )"; |
| |
| std::vector<uint32_t> spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, cs_src, spv); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MaxSampleMaskWords) { |
| TEST_DESCRIPTION("Test limit of maxSampleMaskWords"); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-pCode-08451"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitFramework()); |
| |
| VkPhysicalDeviceDynamicRenderingFeatures dynamic_rendering_features = vku::InitStructHelper(); |
| VkPhysicalDeviceShaderObjectFeaturesEXT shaderObjectFeatures = vku::InitStructHelper(&dynamic_rendering_features); |
| auto features2 = GetPhysicalDeviceFeatures2(shaderObjectFeatures); |
| if (!shaderObjectFeatures.shaderObject) { |
| GTEST_SKIP() << "shaderObject not supported."; |
| } |
| PFN_vkSetPhysicalDeviceLimitsEXT fpvkSetPhysicalDeviceLimitsEXT = nullptr; |
| PFN_vkGetOriginalPhysicalDeviceLimitsEXT fpvkGetOriginalPhysicalDeviceLimitsEXT = nullptr; |
| if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceLimitsEXT, fpvkGetOriginalPhysicalDeviceLimitsEXT)) { |
| GTEST_SKIP() << "Failed to load device profile layer."; |
| } |
| |
| RETURN_IF_SKIP(InitState(nullptr, &features2)); |
| |
| // Set limit to match with hardcoded values in shaders |
| VkPhysicalDeviceProperties props; |
| fpvkGetOriginalPhysicalDeviceLimitsEXT(gpu(), &props.limits); |
| props.limits.maxSampleMaskWords = 3; |
| fpvkSetPhysicalDeviceLimitsEXT(gpu(), &props.limits); |
| |
| char const* fs_src = R"glsl( |
| #version 450 |
| layout(location = 0) out vec4 uFragColor; |
| void main(){ |
| int x = gl_SampleMaskIn[2]; |
| int y = gl_SampleMaskIn[0]; |
| uFragColor = vec4(0,1,0,1) * x * y; |
| } |
| )glsl"; |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, fs_src, SPV_ENV_VULKAN_1_3); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, ConservativeRasterizationPostDepthCoverage) { |
| TEST_DESCRIPTION("Make sure conservativeRasterizationPostDepthCoverage is set if needed."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-FullyCoveredEXT-conservativeRasterizationPostDepthCoverage-04235"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_POST_DEPTH_COVERAGE_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| VkPhysicalDeviceConservativeRasterizationPropertiesEXT conservative_rasterization_props = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(conservative_rasterization_props); |
| if (conservative_rasterization_props.conservativeRasterizationPostDepthCoverage) { |
| GTEST_SKIP() << "conservativeRasterizationPostDepthCoverage not supported"; |
| } |
| |
| const char* fs_src = R"( |
| OpCapability Shader |
| OpCapability SampleMaskPostDepthCoverage |
| OpCapability FragmentFullyCoveredEXT |
| OpExtension "SPV_EXT_fragment_fully_covered" |
| OpExtension "SPV_KHR_post_depth_coverage" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint Fragment %4 "main" %12 |
| OpExecutionMode %4 OriginUpperLeft |
| OpExecutionMode %4 EarlyFragmentTests |
| OpExecutionMode %4 PostDepthCoverage |
| OpDecorate %12 BuiltIn FullyCoveredEXT |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %bool = OpTypeBool |
| %_ptr_Input_bool = OpTypePointer Input %bool |
| %12 = OpVariable %_ptr_Input_bool Input |
| %4 = OpFunction %void None %3 |
| %5 = OpLabel |
| OpReturn |
| OpFunctionEnd |
| )"; |
| |
| std::vector<uint32_t> spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_3, 0, fs_src, spv); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, LocalSizeExceedLimits) { |
| TEST_DESCRIPTION("Create shader where local size exceeds limits."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-x-06429"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-x-06432"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| uint32_t x_count_limit = m_device->phy().limits_.maxComputeWorkGroupCount[0]; |
| |
| std::string cs_src = R"asm( |
| OpCapability Shader |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %main "main" |
| OpExecutionMode %main LocalSize 44 1 1 |
| |
| ; Debug Information |
| OpSource GLSL 460 |
| OpName %main "main" ; id %4 |
| |
| ; Annotations |
| OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %uint = OpTypeInt 32 0 |
| %v3uint = OpTypeVector %uint 3 |
| %uint_44 = OpConstant %uint )asm"; |
| cs_src += std::to_string(x_count_limit); |
| cs_src += R"asm( |
| %uint_1 = OpConstant %uint 1 |
| %gl_WorkGroupSize = OpConstantComposite %v3uint %uint_44 %uint_1 %uint_1 |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| OpReturn |
| OpFunctionEnd)asm"; |
| |
| std::vector<uint32_t> spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, cs_src.c_str(), spv); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingLineWidthSet) { |
| TEST_DESCRIPTION("Draw with shaders outputing lines but not setting line width dynamic state."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08619"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| VkPhysicalDeviceFeatures features; |
| GetPhysicalDeviceFeatures(&features); |
| if (features.geometryShader == VK_FALSE) { |
| GTEST_SKIP() << "geometryShader not supported."; |
| } |
| InitDynamicRenderTarget(); |
| |
| static char const geom_src[] = R"glsl( |
| #version 460 |
| layout(triangles) in; |
| layout(line_strip, max_vertices=2) out; |
| void main() { |
| gl_Position = vec4(1); |
| EmitVertex(); |
| } |
| )glsl"; |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_GEOMETRY_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], kVertexMinimalGlsl)); |
| const vkt::Shader geomShader(*m_device, stages[1], GLSLToSPV(stages[1], geom_src)); |
| const vkt::Shader fragShader(*m_device, stages[2], GLSLToSPV(stages[2], kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_LINE_WIDTH}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 1u, &stages[1], &geomShader.handle()); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidViewportCount) { |
| TEST_DESCRIPTION("Draw with a shader that uses PrimitiveShadingRateKHR with invalid viewport count."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-primitiveFragmentShadingRateWithMultipleViewports-08642"); |
| |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineFragmentShadingRate); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| VkPhysicalDeviceFragmentShadingRatePropertiesKHR fsr_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fsr_properties); |
| if (fsr_properties.primitiveFragmentShadingRateWithMultipleViewports) { |
| GTEST_SKIP() << "required primitiveFragmentShadingRateWithMultipleViewports to be unsupported."; |
| } |
| |
| char const* vsSource = R"glsl( |
| #version 450 |
| #extension GL_EXT_fragment_shading_rate : enable |
| void main() { |
| gl_PrimitiveShadingRateEXT = gl_ShadingRateFlag4VerticalPixelsEXT | gl_ShadingRateFlag4HorizontalPixelsEXT; |
| } |
| )glsl"; |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], vsSource)); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| VkViewport viewports[2]; |
| viewports[0] = {0.0f, 0.0f, 100.0f, 100.0f, 0.0f, 1.0f}; |
| viewports[1] = {0.0f, 100.0f, 100.0f, 100.0f, 0.0f, 1.0f}; |
| vk::CmdSetViewportWithCountEXT(m_commandBuffer->handle(), 2u, viewports); |
| VkRect2D scissors[2]; |
| scissors[0] = {{0, 0}, {100u, 100u}}; |
| scissors[1] = {{0, 100}, {100u, 100u}}; |
| vk::CmdSetScissorWithCountEXT(m_commandBuffer->handle(), 2u, scissors); |
| VkExtent2D fragmentSize = {1u, 1u}; |
| VkFragmentShadingRateCombinerOpKHR combinerOps[2] = {VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, |
| VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR}; |
| vk::CmdSetFragmentShadingRateKHR(m_commandBuffer->handle(), &fragmentSize, combinerOps); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, AlphaToCoverage) { |
| TEST_DESCRIPTION("Draw with fragment shader missing alpha to coverage."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-alphaToCoverageEnable-08920"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| static const char frag_src[] = R"glsl( |
| #version 460 |
| layout(location = 1) out vec4 uFragColor; |
| void main(){ |
| uFragColor = vec4(0,1,0,1); |
| } |
| )glsl"; |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], frag_src)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_LINE_WIDTH}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdSetAlphaToCoverageEnableEXT(m_commandBuffer->handle(), VK_TRUE); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingLineRasterizationMode) { |
| TEST_DESCRIPTION("Draw with shaders outputing lines but not setting line rasterization mode dynamic state."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08668"); |
| |
| AddRequiredExtensions(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| VkPhysicalDeviceFeatures features; |
| GetPhysicalDeviceFeatures(&features); |
| if (features.geometryShader == VK_FALSE) { |
| GTEST_SKIP() << "geometryShader not supported."; |
| } |
| InitDynamicRenderTarget(); |
| |
| static char const geom_src[] = R"glsl( |
| #version 460 |
| layout(triangles) in; |
| layout(line_strip, max_vertices=2) out; |
| void main() { |
| gl_Position = vec4(1); |
| EmitVertex(); |
| } |
| )glsl"; |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_GEOMETRY_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], kVertexMinimalGlsl)); |
| const vkt::Shader geomShader(*m_device, stages[1], GLSLToSPV(stages[1], geom_src)); |
| const vkt::Shader fragShader(*m_device, stages[2], GLSLToSPV(stages[2], kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 1u, &stages[1], &geomShader.handle()); |
| vk::CmdSetLineStippleEnableEXT(m_commandBuffer->handle(), VK_FALSE); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingLineStippleEnable) { |
| TEST_DESCRIPTION("Draw with shaders outputing lines but not setting line stipple enable dynamic state."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08671"); |
| |
| AddRequiredExtensions(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| VkPhysicalDeviceFeatures features; |
| GetPhysicalDeviceFeatures(&features); |
| if (features.geometryShader == VK_FALSE) { |
| GTEST_SKIP() << "geometryShader not supported."; |
| } |
| InitDynamicRenderTarget(); |
| |
| static char const geom_src[] = R"glsl( |
| #version 460 |
| layout(triangles) in; |
| layout(line_strip, max_vertices=2) out; |
| void main() { |
| gl_Position = vec4(1); |
| EmitVertex(); |
| } |
| )glsl"; |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_GEOMETRY_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], kVertexMinimalGlsl)); |
| const vkt::Shader geomShader(*m_device, stages[1], GLSLToSPV(stages[1], geom_src)); |
| const vkt::Shader fragShader(*m_device, stages[2], GLSLToSPV(stages[2], kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates({VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT}); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdSetLineRasterizationModeEXT(m_commandBuffer->handle(), VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT); |
| vk::CmdBindShadersEXT(m_commandBuffer->handle(), 1u, &stages[1], &geomShader.handle()); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidColorWriteMask) { |
| TEST_DESCRIPTION("Draw with invalid color write mask."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-09116"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| VkFormat format = VK_FORMAT_E5B9G9R9_UFLOAT_PACK32; |
| VkFormatProperties props; |
| vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), format, &props); |
| |
| if ((props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0) { |
| GTEST_SKIP() << "VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 not supported as color attachment."; |
| } |
| |
| VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = vku::InitStructHelper(); |
| imageFormatInfo.format = format; |
| imageFormatInfo.type = VK_IMAGE_TYPE_2D; |
| imageFormatInfo.tiling = VK_IMAGE_TILING_OPTIMAL; |
| imageFormatInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| VkImageFormatProperties2 imageFormatProperties = vku::InitStructHelper(); |
| auto res = vk::GetPhysicalDeviceImageFormatProperties2(m_device->phy(), &imageFormatInfo, &imageFormatProperties); |
| if (res == VK_ERROR_FORMAT_NOT_SUPPORTED) { |
| GTEST_SKIP() << "image format not supported as color attachment."; |
| } |
| |
| VkImageObj image(m_device); |
| image.Init(32, 32, 1, format, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(image_view); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| VkColorComponentFlags colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; |
| vk::CmdSetColorWriteMaskEXT(m_commandBuffer->handle(), 0u, 1u, &colorWriteMask); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, Mismatched64BitAttributeType) { |
| TEST_DESCRIPTION("Draw with vertex format not matching vertex input format."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-format-08936"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const VkFormat format = VK_FORMAT_R64_SINT; |
| |
| VkFormatProperties2 formatProperties = vku::InitStructHelper(); |
| vk::GetPhysicalDeviceFormatProperties2(m_device->phy(), format, &formatProperties); |
| |
| if ((formatProperties.formatProperties.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) == 0) { |
| GTEST_SKIP() << "format not supported."; |
| } |
| |
| static const char vert_src[] = R"glsl( |
| #version 460 |
| layout(location = 0) in int pos; |
| void main() { |
| gl_Position = vec4(pos); |
| } |
| )glsl"; |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], vert_src)); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| |
| VkVertexInputBindingDescription2EXT vertexBindingDescription = vku::InitStructHelper(); |
| vertexBindingDescription.binding = 0u; |
| vertexBindingDescription.stride = 16u; |
| vertexBindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; |
| vertexBindingDescription.divisor = 1u; |
| |
| VkVertexInputAttributeDescription2EXT vertexAttributeDescription = vku::InitStructHelper(); |
| vertexAttributeDescription.location = 0u; |
| vertexAttributeDescription.binding = 0u; |
| vertexAttributeDescription.format = format; |
| vertexAttributeDescription.offset = 0u; |
| |
| vk::CmdSetVertexInputEXT(m_commandBuffer->handle(), 1u, &vertexBindingDescription, 1u, &vertexAttributeDescription); |
| |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, Mismatched32BitAttributeType) { |
| TEST_DESCRIPTION("Draw with vertex format not matching vertex input format."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-format-08937"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| static const char vert_src[] = R"glsl( |
| #version 460 |
| #extension GL_EXT_shader_explicit_arithmetic_types : enable |
| layout(location = 0) in int64_t pos; |
| void main() { |
| gl_Position = vec4(pos); |
| } |
| )glsl"; |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], vert_src)); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| |
| VkVertexInputBindingDescription2EXT vertexBindingDescription = vku::InitStructHelper(); |
| vertexBindingDescription.binding = 0u; |
| vertexBindingDescription.stride = 16u; |
| vertexBindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; |
| vertexBindingDescription.divisor = 1u; |
| |
| VkVertexInputAttributeDescription2EXT vertexAttributeDescription = vku::InitStructHelper(); |
| vertexAttributeDescription.location = 0u; |
| vertexAttributeDescription.binding = 0u; |
| vertexAttributeDescription.format = VK_FORMAT_R32_SINT; |
| vertexAttributeDescription.offset = 0u; |
| |
| vk::CmdSetVertexInputEXT(m_commandBuffer->handle(), 1u, &vertexBindingDescription, 1u, &vertexAttributeDescription); |
| |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MismatchedFormat64Components) { |
| TEST_DESCRIPTION("Draw with vertex format components not matching vertex input format components."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-09203"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const VkFormat format = VK_FORMAT_R64G64B64_SINT; |
| |
| VkFormatProperties2 formatProperties = vku::InitStructHelper(); |
| vk::GetPhysicalDeviceFormatProperties2(m_device->phy(), format, &formatProperties); |
| |
| if ((formatProperties.formatProperties.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) == 0) { |
| GTEST_SKIP() << "format not supported."; |
| } |
| |
| static const char vert_src[] = R"glsl( |
| #version 460 |
| #extension GL_EXT_shader_explicit_arithmetic_types : enable |
| layout(location = 0) in i64vec4 pos; |
| void main() { |
| gl_Position = vec4(pos.xy, pos.xy); |
| } |
| )glsl"; |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], vert_src)); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| |
| VkVertexInputBindingDescription2EXT vertexBindingDescription = vku::InitStructHelper(); |
| vertexBindingDescription.binding = 0u; |
| vertexBindingDescription.stride = 16u; |
| vertexBindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; |
| vertexBindingDescription.divisor = 1u; |
| |
| VkVertexInputAttributeDescription2EXT vertexAttributeDescription = vku::InitStructHelper(); |
| vertexAttributeDescription.location = 0u; |
| vertexAttributeDescription.binding = 0u; |
| vertexAttributeDescription.format = format; |
| vertexAttributeDescription.offset = 0u; |
| |
| vk::CmdSetVertexInputEXT(m_commandBuffer->handle(), 1u, &vertexBindingDescription, 1u, &vertexAttributeDescription); |
| |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, DescriptorNotUpdated) { |
| TEST_DESCRIPTION("Draw with shaders using a descriptor set that was never updated."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-08114"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| OneOffDescriptorSet vert_descriptor_set(m_device, |
| { |
| {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, nullptr}, |
| }); |
| OneOffDescriptorSet frag_descriptor_set( |
| m_device, { |
| {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}, |
| }); |
| |
| vkt::PipelineLayout pipeline_layout(*m_device, {&vert_descriptor_set.layout_, &frag_descriptor_set.layout_}); |
| |
| static const char vert_src[] = R"glsl( |
| #version 460 |
| layout(location = 0) out vec2 uv; |
| layout(set = 0, binding = 0) buffer Buffer { |
| vec4 pos; |
| } buf; |
| void main() { |
| uv = vec2(gl_VertexIndex & 1, (gl_VertexIndex >> 1) & 1); |
| gl_Position = vec4(buf.pos); |
| } |
| )glsl"; |
| |
| static const char frag_src[] = R"glsl( |
| #version 460 |
| layout(set = 1, binding = 0) uniform sampler2D s; |
| layout(location = 0) in vec2 uv; |
| layout(location = 0) out vec4 uFragColor; |
| void main(){ |
| uFragColor = texture(s, uv); |
| } |
| )glsl"; |
| |
| const auto vert_spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, vert_src); |
| const auto frag_spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, frag_src); |
| |
| VkDescriptorSetLayout descriptor_set_layouts[] = {vert_descriptor_set.layout_.handle(), frag_descriptor_set.layout_.handle()}; |
| |
| VkShaderCreateInfoEXT vert_create_info = vku::InitStructHelper(); |
| vert_create_info.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| vert_create_info.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| vert_create_info.codeSize = vert_spv.size() * sizeof(vert_spv[0]); |
| vert_create_info.pCode = vert_spv.data(); |
| vert_create_info.pName = "main"; |
| vert_create_info.setLayoutCount = 2u; |
| vert_create_info.pSetLayouts = descriptor_set_layouts; |
| |
| VkShaderCreateInfoEXT frag_create_info = vku::InitStructHelper(); |
| frag_create_info.stage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| frag_create_info.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| frag_create_info.codeSize = frag_spv.size() * sizeof(frag_spv[0]); |
| frag_create_info.pCode = frag_spv.data(); |
| frag_create_info.pName = "main"; |
| frag_create_info.setLayoutCount = 2u; |
| frag_create_info.pSetLayouts = descriptor_set_layouts; |
| |
| const vkt::Shader vertShader(*m_device, vert_create_info); |
| const vkt::Shader fragShader(*m_device, frag_create_info); |
| |
| vkt::Buffer buffer(*m_device, 32, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| vert_descriptor_set.WriteDescriptorBufferInfo(0, buffer.handle(), 0, 32, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); |
| vert_descriptor_set.UpdateDescriptorSets(); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0u, 1u, |
| &vert_descriptor_set.set_, 0u, nullptr); |
| vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 1u, 1u, |
| &frag_descriptor_set.set_, 0u, nullptr); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, ComputeVaryingAndFullSubgroups) { |
| TEST_DESCRIPTION("Dispatch with compute shader using required full subgroups and allow varying subgroup size flags."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-flags-08416"); |
| |
| AddRequiredExtensions(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::subgroupSizeControl); |
| AddRequiredFeature(vkt::Feature::computeFullSubgroups); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| VkPhysicalDeviceSubgroupSizeControlPropertiesEXT subgroup_size_control_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(subgroup_size_control_properties); |
| |
| std::string comp_src = R"glsl( |
| #version 460 |
| layout(local_size_x = )glsl"; |
| comp_src += std::to_string(subgroup_size_control_properties.maxSubgroupSize + 1u); |
| comp_src += R"glsl() in; |
| void main() {} |
| )glsl"; |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, comp_src.c_str()); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.flags = VK_SHADER_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT | VK_SHADER_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT; |
| createInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, ComputeVaryingSubgroups) { |
| TEST_DESCRIPTION("Dispatch with compute shader using required full subgroups and allow varying subgroup size flags."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-flags-08417"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::computeFullSubgroups); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| VkPhysicalDeviceVulkan11Properties properties11 = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(properties11); |
| |
| std::string comp_src = R"glsl( |
| #version 460 |
| layout(local_size_x = )glsl"; |
| comp_src += std::to_string(properties11.subgroupSize + 1u); |
| comp_src += R"glsl() in; |
| void main() {} |
| )glsl"; |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, comp_src.c_str()); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.flags = VK_SHADER_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT; |
| createInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, GeometryShaderMaxOutputVertices) { |
| TEST_DESCRIPTION("Create geometry shader with output vertices higher than maximum."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-pCode-08454"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| VkPhysicalDeviceFeatures features; |
| GetPhysicalDeviceFeatures(&features); |
| if (features.geometryShader == VK_FALSE) { |
| GTEST_SKIP() << "geometryShader not supported."; |
| } |
| |
| std::string geom_src = R"( |
| OpCapability Geometry |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint Geometry %main "main" %_ |
| OpExecutionMode %main Triangles |
| OpExecutionMode %main Invocations 1 |
| OpExecutionMode %main OutputTriangleStrip |
| OpExecutionMode %main OutputVertices )"; |
| geom_src += std::to_string(m_device->phy().limits_.maxGeometryOutputVertices + 1); |
| geom_src += R"( |
| ; Debug Information |
| OpSource GLSL 460 |
| OpName %main "main" ; id %4 |
| OpName %gl_PerVertex "gl_PerVertex" ; id %11 |
| OpMemberName %gl_PerVertex 0 "gl_Position" |
| OpMemberName %gl_PerVertex 1 "gl_PointSize" |
| OpMemberName %gl_PerVertex 2 "gl_ClipDistance" |
| OpMemberName %gl_PerVertex 3 "gl_CullDistance" |
| OpName %_ "" ; id %13 |
| |
| ; Annotations |
| OpMemberDecorate %gl_PerVertex 0 BuiltIn Position |
| OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize |
| OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance |
| OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance |
| OpDecorate %gl_PerVertex Block |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %v4float = OpTypeVector %float 4 |
| %uint = OpTypeInt 32 0 |
| %uint_1 = OpConstant %uint 1 |
| %_arr_float_uint_1 = OpTypeArray %float %uint_1 |
| %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 |
| %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex |
| %_ = OpVariable %_ptr_Output_gl_PerVertex Output |
| %int = OpTypeInt 32 1 |
| %int_0 = OpConstant %int 0 |
| %float_1 = OpConstant %float 1 |
| %17 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 |
| %_ptr_Output_v4float = OpTypePointer Output %v4float |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %19 = OpAccessChain %_ptr_Output_v4float %_ %int_0 |
| OpStore %19 %17 |
| OpEmitVertex |
| OpReturn |
| OpFunctionEnd)"; |
| |
| std::vector<uint32_t> spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, geom_src.c_str(), spv); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_GEOMETRY_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, GeometryShaderMaxInvocations) { |
| TEST_DESCRIPTION("Create geometry shader with invocations higher than maximum."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-pCode-08455"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| VkPhysicalDeviceFeatures features; |
| GetPhysicalDeviceFeatures(&features); |
| if (features.geometryShader == VK_FALSE) { |
| GTEST_SKIP() << "geometryShader not supported."; |
| } |
| |
| std::string geom_src = R"( |
| OpCapability Geometry |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint Geometry %main "main" %_ |
| OpExecutionMode %main Triangles |
| OpExecutionMode %main Invocations )"; |
| geom_src += std::to_string(m_device->phy().limits_.maxGeometryShaderInvocations + 1); |
| geom_src += R"( |
| OpExecutionMode %main OutputTriangleStrip |
| OpExecutionMode %main OutputVertices 2 |
| ; Debug Information |
| OpSource GLSL 460 |
| OpName %main "main" ; id %4 |
| OpName %gl_PerVertex "gl_PerVertex" ; id %11 |
| OpMemberName %gl_PerVertex 0 "gl_Position" |
| OpMemberName %gl_PerVertex 1 "gl_PointSize" |
| OpMemberName %gl_PerVertex 2 "gl_ClipDistance" |
| OpMemberName %gl_PerVertex 3 "gl_CullDistance" |
| OpName %_ "" ; id %13 |
| |
| ; Annotations |
| OpMemberDecorate %gl_PerVertex 0 BuiltIn Position |
| OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize |
| OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance |
| OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance |
| OpDecorate %gl_PerVertex Block |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %v4float = OpTypeVector %float 4 |
| %uint = OpTypeInt 32 0 |
| %uint_1 = OpConstant %uint 1 |
| %_arr_float_uint_1 = OpTypeArray %float %uint_1 |
| %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 |
| %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex |
| %_ = OpVariable %_ptr_Output_gl_PerVertex Output |
| %int = OpTypeInt 32 1 |
| %int_0 = OpConstant %int 0 |
| %float_1 = OpConstant %float 1 |
| %17 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 |
| %_ptr_Output_v4float = OpTypePointer Output %v4float |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %19 = OpAccessChain %_ptr_Output_v4float %_ %int_0 |
| OpStore %19 %17 |
| OpEmitVertex |
| OpReturn |
| OpFunctionEnd)"; |
| |
| std::vector<uint32_t> spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, geom_src.c_str(), spv); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_GEOMETRY_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingImageFilterLinearBit) { |
| TEST_DESCRIPTION("Draw with shaders sampling from an image which does not have required filter linear bit."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-magFilter-04553"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| VkFormat format = VK_FORMAT_R16_SINT; |
| VkFormatProperties props = {}; |
| vk::GetPhysicalDeviceFormatProperties(gpu(), format, &props); |
| |
| if ((props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) > 0 || |
| (props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) == 0) { |
| GTEST_SKIP() << "Required image features not supported."; |
| } |
| |
| OneOffDescriptorSet descriptor_set(m_device, |
| { |
| {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}, |
| }); |
| |
| vkt::PipelineLayout pipeline_layout(*m_device, {&descriptor_set.layout_}); |
| |
| static const char frag_src[] = R"glsl( |
| #version 460 |
| layout(set=0, binding=0) uniform isampler2D s; |
| layout(location=0) out vec4 x; |
| void main(){ |
| x = texture(s, vec2(1)); |
| } |
| )glsl"; |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl), |
| &descriptor_set.layout_.handle()); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, frag_src), |
| &descriptor_set.layout_.handle()); |
| |
| VkImageObj image(m_device); |
| image.Init(32, 32, 1, format, VK_IMAGE_USAGE_SAMPLED_BIT); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo(); |
| sampler_info.minFilter = VK_FILTER_LINEAR; |
| sampler_info.compareEnable = VK_FALSE; |
| vkt::Sampler sampler(*m_device, sampler_info); |
| |
| descriptor_set.WriteDescriptorImageInfo(0, image_view, sampler.handle()); |
| descriptor_set.UpdateDescriptorSets(); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0u, 1u, |
| &descriptor_set.set_, 0u, nullptr); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MaxMultiviewInstanceIndex) { |
| TEST_DESCRIPTION("Draw with a read only depth stencil attachment and invalid stencil op."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-maxMultiviewInstanceIndex-02688"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredFeature(vkt::Feature::multiview); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| VkPhysicalDeviceMultiviewProperties multiview_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(multiview_properties); |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| |
| VkImageObj img(m_device); |
| img.Init(m_width, m_height, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::ImageView view = img.CreateView(); |
| |
| VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper(); |
| color_attachment.imageView = view; |
| color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| |
| VkRenderingInfoKHR renderingInfo = vku::InitStructHelper(); |
| renderingInfo.renderArea = {{0, 0}, {100u, 100u}}; |
| renderingInfo.layerCount = 1u; |
| renderingInfo.colorAttachmentCount = 1u; |
| renderingInfo.pColorAttachments = &color_attachment; |
| renderingInfo.viewMask = 0x1; |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRendering(renderingInfo); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 3u, 1u, 0u, multiview_properties.maxMultiviewInstanceIndex); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/5208 |
| TEST_F(NegativeShaderObject, DISABLED_MaxFragmentDualSrcAttachmentsDynamicBlendEnable) { |
| TEST_DESCRIPTION( |
| "Test drawing with dual source blending with too many fragment output attachments, but using dynamic blending."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| VkPhysicalDeviceFeatures features; |
| GetPhysicalDeviceFeatures(&features); |
| if (features.dualSrcBlend == VK_FALSE) { |
| GTEST_SKIP() << "dualSrcBlend feature is not available"; |
| } |
| |
| InitDynamicRenderTarget(); |
| |
| uint32_t count = m_device->phy().limits_.maxFragmentDualSrcAttachments + 1; |
| |
| std::stringstream fsSource; |
| fsSource << "#version 450\n"; |
| for (uint32_t i = 0; i < count; ++i) { |
| fsSource << "layout(location = " << i << ") out vec4 c" << i << ";\n"; |
| } |
| fsSource << " void main() {\n"; |
| for (uint32_t i = 0; i < count; ++i) { |
| fsSource << "c" << i << " = vec4(0.0f);\n"; |
| } |
| fsSource << "}"; |
| |
| const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, fsSource.str().c_str())); |
| |
| VkImageObj img1(m_device); |
| img1.Init(m_width, m_height, 1, m_render_target_fmt, |
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| VkImageObj img2(m_device); |
| img2.Init(m_width, m_height, 1, m_render_target_fmt, |
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| |
| vkt::ImageView view1 = img1.CreateView(); |
| vkt::ImageView view2 = img2.CreateView(); |
| |
| VkRenderingAttachmentInfo attachments[2]; |
| attachments[0] = vku::InitStructHelper(); |
| attachments[0].imageView = view1; |
| attachments[0].imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachments[1] = vku::InitStructHelper(); |
| attachments[1].imageView = view2; |
| attachments[1].imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| |
| VkRenderingInfoKHR renderingInfo = vku::InitStructHelper(); |
| renderingInfo.renderArea = {{0, 0}, {100u, 100u}}; |
| renderingInfo.layerCount = 1u; |
| renderingInfo.colorAttachmentCount = 2u; |
| renderingInfo.pColorAttachments = attachments; |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRendering(renderingInfo); |
| |
| SetDefaultDynamicStates(); |
| |
| VkBool32 color_blend_enabled[2] = {VK_TRUE, VK_FALSE}; |
| VkColorBlendEquationEXT color_blend_equation = { |
| VK_BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_OP_ADD, |
| VK_BLEND_FACTOR_SRC_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_OP_ADD}; |
| VkColorComponentFlags color_component_flags = VK_COLOR_COMPONENT_R_BIT; |
| |
| vk::CmdSetColorBlendEnableEXT(m_commandBuffer->handle(), 0, 1, &color_blend_enabled[0]); // enables |
| vk::CmdSetColorBlendEnableEXT(m_commandBuffer->handle(), 1, 1, &color_blend_enabled[1]); |
| vk::CmdSetColorBlendEquationEXT(m_commandBuffer->handle(), 0, 1, &color_blend_equation); |
| vk::CmdSetColorWriteMaskEXT(m_commandBuffer->handle(), 0, 1, &color_component_flags); |
| |
| VkColorBlendAdvancedEXT colorBlendAdvanced; |
| colorBlendAdvanced.advancedBlendOp = VK_BLEND_OP_ADD; |
| colorBlendAdvanced.srcPremultiplied = VK_FALSE; |
| colorBlendAdvanced.dstPremultiplied = VK_FALSE; |
| colorBlendAdvanced.blendOverlap = VK_BLEND_OVERLAP_UNCORRELATED_EXT; |
| colorBlendAdvanced.clampResults = VK_FALSE; |
| vk::CmdSetColorBlendAdvancedEXT(m_commandBuffer->handle(), 0u, 1u, &colorBlendAdvanced); |
| vk::CmdSetColorBlendAdvancedEXT(m_commandBuffer->handle(), 1u, 1u, &colorBlendAdvanced); |
| |
| BindVertFragShader(vertShader, fragShader); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-Fragment-06427"); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| // disables blending so no error should appear |
| vk::CmdSetColorBlendEnableEXT(m_commandBuffer->handle(), 0, 1, &color_blend_enabled[1]); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| } |
| |
| TEST_F(NegativeShaderObject, PrimitivesGeneratedQuery) { |
| TEST_DESCRIPTION("Draw with primitives generated query."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-primitivesGeneratedQueryWithRasterizerDiscard-06708"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME); |
| VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT pgq_features = vku::InitStructHelper(); |
| |
| RETURN_IF_SKIP(InitFramework()); |
| |
| VkPhysicalDeviceDynamicRenderingFeatures dynamic_rendering_features = vku::InitStructHelper(&pgq_features); |
| VkPhysicalDeviceShaderObjectFeaturesEXT shader_object_features = vku::InitStructHelper(&dynamic_rendering_features); |
| auto features2 = GetPhysicalDeviceFeatures2(shader_object_features); |
| |
| pgq_features.primitivesGeneratedQueryWithRasterizerDiscard = VK_FALSE; |
| |
| if (!shader_object_features.shaderObject) { |
| GTEST_SKIP() << "shaderObject not supported."; |
| } |
| if (!pgq_features.primitivesGeneratedQuery) { |
| GTEST_SKIP() << "primitivesGeneratedQuery not supported."; |
| } |
| |
| RETURN_IF_SKIP(InitState(nullptr, &features2)); |
| |
| InitDynamicRenderTarget(); |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentMinimalGlsl)); |
| |
| vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT, 1); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool.handle(), 0, 0); |
| vk::CmdSetRasterizerDiscardEnableEXT(m_commandBuffer->handle(), VK_TRUE); |
| vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); |
| vk::CmdEndQuery(m_commandBuffer->handle(), query_pool.handle(), 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, CooperativeMatrix) { |
| TEST_DESCRIPTION("Test cooperative matrix with shader objects"); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-RuntimeSpirv-OpTypeCooperativeMatrixKHR-08974"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| |
| AddRequiredExtensions(VK_KHR_COOPERATIVE_MATRIX_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::shaderFloat16); |
| AddRequiredFeature(vkt::Feature::cooperativeMatrix); |
| AddRequiredFeature(vkt::Feature::vulkanMemoryModel); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| std::vector<VkDescriptorSetLayoutBinding> bindings(0); |
| const vkt::DescriptorSetLayout dsl(*m_device, bindings); |
| const vkt::PipelineLayout pl(*m_device, {&dsl}); |
| |
| // Tests are assume that Float16 3*5 is not available |
| char const* comp_src = R"glsl( |
| #version 450 |
| #pragma use_vulkan_memory_model |
| #extension GL_KHR_cooperative_matrix : enable |
| #extension GL_KHR_shader_subgroup_basic : enable |
| #extension GL_KHR_memory_scope_semantics : enable |
| #extension GL_EXT_shader_explicit_arithmetic_types_float16 : enable |
| layout(local_size_x = 32) in; |
| void main() { |
| coopmat<float16_t, gl_ScopeSubgroup, 3, 5, gl_MatrixUseAccumulator> badSize = coopmat<float16_t, gl_ScopeSubgroup, 3, 5, gl_MatrixUseAccumulator>(float16_t(0.0)); |
| } |
| )glsl"; |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, comp_src); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MismatchedTessellationSubdivision) { |
| TEST_DESCRIPTION("Create linked tessellation control and evaluation shaders with different subdivision."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateShadersEXT-pCreateInfos-08867"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* tesc_src = R"( |
| OpCapability Tessellation |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationControl %main "main" %gl_TessLevelOuter %gl_TessLevelInner |
| OpExecutionMode %main OutputVertices 3 |
| OpExecutionMode %main Quads |
| |
| ; Debug Information |
| OpSource GLSL 460 |
| OpName %main "main" ; id %4 |
| OpName %gl_TessLevelOuter "gl_TessLevelOuter" ; id %11 |
| OpName %gl_TessLevelInner "gl_TessLevelInner" ; id %24 |
| |
| ; Annotations |
| OpDecorate %gl_TessLevelOuter Patch |
| OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter |
| OpDecorate %gl_TessLevelInner Patch |
| OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %uint = OpTypeInt 32 0 |
| %uint_4 = OpConstant %uint 4 |
| %_arr_float_uint_4 = OpTypeArray %float %uint_4 |
| %_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4 |
| %gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output |
| %int = OpTypeInt 32 1 |
| %int_0 = OpConstant %int 0 |
| %int_1 = OpConstant %int 1 |
| %int_2 = OpConstant %int 2 |
| %float_1 = OpConstant %float 1 |
| %_ptr_Output_float = OpTypePointer Output %float |
| %uint_2 = OpConstant %uint 2 |
| %_arr_float_uint_2 = OpTypeArray %float %uint_2 |
| %_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2 |
| %gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %18 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2 |
| OpStore %18 %float_1 |
| %19 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1 |
| OpStore %19 %float_1 |
| %20 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0 |
| OpStore %20 %float_1 |
| %25 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0 |
| OpStore %25 %float_1 |
| OpReturn |
| OpFunctionEnd)"; |
| |
| const char* tese_src = R"( |
| OpCapability Tessellation |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationEvaluation %main "main" %_ |
| OpExecutionMode %main Triangles |
| OpExecutionMode %main SpacingFractionalOdd |
| OpExecutionMode %main VertexOrderCw |
| |
| ; Debug Information |
| OpSource GLSL 460 |
| OpName %main "main" ; id %4 |
| OpName %gl_PerVertex "gl_PerVertex" ; id %11 |
| OpMemberName %gl_PerVertex 0 "gl_Position" |
| OpMemberName %gl_PerVertex 1 "gl_PointSize" |
| OpMemberName %gl_PerVertex 2 "gl_ClipDistance" |
| OpMemberName %gl_PerVertex 3 "gl_CullDistance" |
| OpName %_ "" ; id %13 |
| |
| ; Annotations |
| OpMemberDecorate %gl_PerVertex 0 BuiltIn Position |
| OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize |
| OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance |
| OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance |
| OpDecorate %gl_PerVertex Block |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %v4float = OpTypeVector %float 4 |
| %uint = OpTypeInt 32 0 |
| %uint_1 = OpConstant %uint 1 |
| %_arr_float_uint_1 = OpTypeArray %float %uint_1 |
| %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 |
| %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex |
| %_ = OpVariable %_ptr_Output_gl_PerVertex Output |
| %int = OpTypeInt 32 1 |
| %int_0 = OpConstant %int 0 |
| %float_1 = OpConstant %float 1 |
| %17 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 |
| %_ptr_Output_v4float = OpTypePointer Output %v4float |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %19 = OpAccessChain %_ptr_Output_v4float %_ %int_0 |
| OpStore %19 %17 |
| OpReturn |
| OpFunctionEnd)"; |
| |
| std::vector<uint32_t> tesc_spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, tesc_src, tesc_spv); |
| std::vector<uint32_t> tese_spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, tese_src, tese_spv); |
| |
| VkShaderCreateInfoEXT createInfos[2]; |
| createInfos[0] = vku::InitStructHelper(); |
| createInfos[0].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[0].stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; |
| createInfos[0].nextStage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| createInfos[0].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[0].codeSize = tesc_spv.size() * sizeof(tesc_spv[0]); |
| createInfos[0].pCode = tesc_spv.data(); |
| createInfos[0].pName = "main"; |
| createInfos[1] = vku::InitStructHelper(); |
| createInfos[1].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[1].stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| createInfos[1].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[1].codeSize = tese_spv.size() * sizeof(tese_spv[0]); |
| createInfos[1].pCode = tese_spv.data(); |
| createInfos[1].pName = "main"; |
| |
| VkShaderEXT shaders[2]; |
| vk::CreateShadersEXT(m_device->handle(), 2u, createInfos, nullptr, shaders); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MismatchedTessellationOrientation) { |
| TEST_DESCRIPTION("Create linked tessellation control and evaluation shaders with different orientations."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateShadersEXT-pCreateInfos-08868"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* tesc_src = R"( |
| OpCapability Tessellation |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationControl %main "main" %gl_TessLevelOuter %gl_TessLevelInner |
| OpExecutionMode %main OutputVertices 3 |
| OpExecutionMode %main VertexOrderCcw |
| |
| ; Debug Information |
| OpSource GLSL 460 |
| OpName %main "main" ; id %4 |
| OpName %gl_TessLevelOuter "gl_TessLevelOuter" ; id %11 |
| OpName %gl_TessLevelInner "gl_TessLevelInner" ; id %24 |
| |
| ; Annotations |
| OpDecorate %gl_TessLevelOuter Patch |
| OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter |
| OpDecorate %gl_TessLevelInner Patch |
| OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %uint = OpTypeInt 32 0 |
| %uint_4 = OpConstant %uint 4 |
| %_arr_float_uint_4 = OpTypeArray %float %uint_4 |
| %_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4 |
| %gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output |
| %int = OpTypeInt 32 1 |
| %int_0 = OpConstant %int 0 |
| %int_1 = OpConstant %int 1 |
| %int_2 = OpConstant %int 2 |
| %float_1 = OpConstant %float 1 |
| %_ptr_Output_float = OpTypePointer Output %float |
| %uint_2 = OpConstant %uint 2 |
| %_arr_float_uint_2 = OpTypeArray %float %uint_2 |
| %_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2 |
| %gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %18 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2 |
| OpStore %18 %float_1 |
| %19 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1 |
| OpStore %19 %float_1 |
| %20 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0 |
| OpStore %20 %float_1 |
| %25 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0 |
| OpStore %25 %float_1 |
| OpReturn |
| OpFunctionEnd)"; |
| |
| const char* tese_src = R"( |
| OpCapability Tessellation |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationEvaluation %main "main" %_ |
| OpExecutionMode %main Triangles |
| OpExecutionMode %main SpacingFractionalOdd |
| OpExecutionMode %main VertexOrderCw |
| |
| ; Debug Information |
| OpSource GLSL 460 |
| OpName %main "main" ; id %4 |
| OpName %gl_PerVertex "gl_PerVertex" ; id %11 |
| OpMemberName %gl_PerVertex 0 "gl_Position" |
| OpMemberName %gl_PerVertex 1 "gl_PointSize" |
| OpMemberName %gl_PerVertex 2 "gl_ClipDistance" |
| OpMemberName %gl_PerVertex 3 "gl_CullDistance" |
| OpName %_ "" ; id %13 |
| |
| ; Annotations |
| OpMemberDecorate %gl_PerVertex 0 BuiltIn Position |
| OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize |
| OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance |
| OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance |
| OpDecorate %gl_PerVertex Block |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %v4float = OpTypeVector %float 4 |
| %uint = OpTypeInt 32 0 |
| %uint_1 = OpConstant %uint 1 |
| %_arr_float_uint_1 = OpTypeArray %float %uint_1 |
| %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 |
| %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex |
| %_ = OpVariable %_ptr_Output_gl_PerVertex Output |
| %int = OpTypeInt 32 1 |
| %int_0 = OpConstant %int 0 |
| %float_1 = OpConstant %float 1 |
| %17 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 |
| %_ptr_Output_v4float = OpTypePointer Output %v4float |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %19 = OpAccessChain %_ptr_Output_v4float %_ %int_0 |
| OpStore %19 %17 |
| OpReturn |
| OpFunctionEnd)"; |
| |
| std::vector<uint32_t> tesc_spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, tesc_src, tesc_spv); |
| std::vector<uint32_t> tese_spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, tese_src, tese_spv); |
| |
| VkShaderCreateInfoEXT createInfos[2]; |
| createInfos[0] = vku::InitStructHelper(); |
| createInfos[0].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[0].stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; |
| createInfos[0].nextStage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| createInfos[0].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[0].codeSize = tesc_spv.size() * sizeof(tesc_spv[0]); |
| createInfos[0].pCode = tesc_spv.data(); |
| createInfos[0].pName = "main"; |
| createInfos[1] = vku::InitStructHelper(); |
| createInfos[1].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[1].stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| createInfos[1].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[1].codeSize = tese_spv.size() * sizeof(tese_spv[0]); |
| createInfos[1].pCode = tese_spv.data(); |
| createInfos[1].pName = "main"; |
| |
| VkShaderEXT shaders[2]; |
| vk::CreateShadersEXT(m_device->handle(), 2u, createInfos, nullptr, shaders); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MismatchedTessellationPointMode) { |
| TEST_DESCRIPTION("Create linked tessellation control with point mode and evaluation shader without."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateShadersEXT-pCreateInfos-08869"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* tesc_src = R"( |
| OpCapability Tessellation |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationControl %main "main" %gl_TessLevelOuter %gl_TessLevelInner |
| OpExecutionMode %main OutputVertices 3 |
| OpExecutionMode %main PointMode |
| |
| ; Debug Information |
| OpSource GLSL 460 |
| OpName %main "main" ; id %4 |
| OpName %gl_TessLevelOuter "gl_TessLevelOuter" ; id %11 |
| OpName %gl_TessLevelInner "gl_TessLevelInner" ; id %24 |
| |
| ; Annotations |
| OpDecorate %gl_TessLevelOuter Patch |
| OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter |
| OpDecorate %gl_TessLevelInner Patch |
| OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %uint = OpTypeInt 32 0 |
| %uint_4 = OpConstant %uint 4 |
| %_arr_float_uint_4 = OpTypeArray %float %uint_4 |
| %_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4 |
| %gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output |
| %int = OpTypeInt 32 1 |
| %int_0 = OpConstant %int 0 |
| %int_1 = OpConstant %int 1 |
| %int_2 = OpConstant %int 2 |
| %float_1 = OpConstant %float 1 |
| %_ptr_Output_float = OpTypePointer Output %float |
| %uint_2 = OpConstant %uint 2 |
| %_arr_float_uint_2 = OpTypeArray %float %uint_2 |
| %_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2 |
| %gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %18 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2 |
| OpStore %18 %float_1 |
| %19 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1 |
| OpStore %19 %float_1 |
| %20 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0 |
| OpStore %20 %float_1 |
| %25 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0 |
| OpStore %25 %float_1 |
| OpReturn |
| OpFunctionEnd)"; |
| |
| const char* tese_src = R"( |
| OpCapability Tessellation |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationEvaluation %main "main" %_ |
| OpExecutionMode %main Triangles |
| OpExecutionMode %main SpacingFractionalOdd |
| OpExecutionMode %main VertexOrderCw |
| |
| ; Debug Information |
| OpSource GLSL 460 |
| OpName %main "main" ; id %4 |
| OpName %gl_PerVertex "gl_PerVertex" ; id %11 |
| OpMemberName %gl_PerVertex 0 "gl_Position" |
| OpMemberName %gl_PerVertex 1 "gl_PointSize" |
| OpMemberName %gl_PerVertex 2 "gl_ClipDistance" |
| OpMemberName %gl_PerVertex 3 "gl_CullDistance" |
| OpName %_ "" ; id %13 |
| |
| ; Annotations |
| OpMemberDecorate %gl_PerVertex 0 BuiltIn Position |
| OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize |
| OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance |
| OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance |
| OpDecorate %gl_PerVertex Block |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %v4float = OpTypeVector %float 4 |
| %uint = OpTypeInt 32 0 |
| %uint_1 = OpConstant %uint 1 |
| %_arr_float_uint_1 = OpTypeArray %float %uint_1 |
| %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 |
| %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex |
| %_ = OpVariable %_ptr_Output_gl_PerVertex Output |
| %int = OpTypeInt 32 1 |
| %int_0 = OpConstant %int 0 |
| %float_1 = OpConstant %float 1 |
| %17 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 |
| %_ptr_Output_v4float = OpTypePointer Output %v4float |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %19 = OpAccessChain %_ptr_Output_v4float %_ %int_0 |
| OpStore %19 %17 |
| OpReturn |
| OpFunctionEnd)"; |
| |
| std::vector<uint32_t> tesc_spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, tesc_src, tesc_spv); |
| std::vector<uint32_t> tese_spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, tese_src, tese_spv); |
| |
| VkShaderCreateInfoEXT createInfos[2]; |
| createInfos[0] = vku::InitStructHelper(); |
| createInfos[0].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[0].stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; |
| createInfos[0].nextStage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| createInfos[0].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[0].codeSize = tesc_spv.size() * sizeof(tesc_spv[0]); |
| createInfos[0].pCode = tesc_spv.data(); |
| createInfos[0].pName = "main"; |
| createInfos[1] = vku::InitStructHelper(); |
| createInfos[1].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[1].stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| createInfos[1].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[1].codeSize = tese_spv.size() * sizeof(tese_spv[0]); |
| createInfos[1].pCode = tese_spv.data(); |
| createInfos[1].pName = "main"; |
| |
| VkShaderEXT shaders[2]; |
| vk::CreateShadersEXT(m_device->handle(), 2u, createInfos, nullptr, shaders); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MismatchedTessellationSpacing) { |
| TEST_DESCRIPTION("Create linked tessellation control and evaluation shaders with different spacing."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateShadersEXT-pCreateInfos-08870"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* tesc_src = R"( |
| OpCapability Tessellation |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationControl %main "main" %gl_TessLevelOuter %gl_TessLevelInner |
| OpExecutionMode %main OutputVertices 3 |
| OpExecutionMode %main SpacingFractionalEven |
| |
| ; Debug Information |
| OpSource GLSL 460 |
| OpName %main "main" ; id %4 |
| OpName %gl_TessLevelOuter "gl_TessLevelOuter" ; id %11 |
| OpName %gl_TessLevelInner "gl_TessLevelInner" ; id %24 |
| |
| ; Annotations |
| OpDecorate %gl_TessLevelOuter Patch |
| OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter |
| OpDecorate %gl_TessLevelInner Patch |
| OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %uint = OpTypeInt 32 0 |
| %uint_4 = OpConstant %uint 4 |
| %_arr_float_uint_4 = OpTypeArray %float %uint_4 |
| %_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4 |
| %gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output |
| %int = OpTypeInt 32 1 |
| %int_0 = OpConstant %int 0 |
| %int_1 = OpConstant %int 1 |
| %int_2 = OpConstant %int 2 |
| %float_1 = OpConstant %float 1 |
| %_ptr_Output_float = OpTypePointer Output %float |
| %uint_2 = OpConstant %uint 2 |
| %_arr_float_uint_2 = OpTypeArray %float %uint_2 |
| %_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2 |
| %gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %18 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2 |
| OpStore %18 %float_1 |
| %19 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1 |
| OpStore %19 %float_1 |
| %20 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0 |
| OpStore %20 %float_1 |
| %25 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0 |
| OpStore %25 %float_1 |
| OpReturn |
| OpFunctionEnd)"; |
| |
| const char* tese_src = R"( |
| OpCapability Tessellation |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationEvaluation %main "main" %_ |
| OpExecutionMode %main Triangles |
| OpExecutionMode %main SpacingFractionalOdd |
| OpExecutionMode %main VertexOrderCw |
| |
| ; Debug Information |
| OpSource GLSL 460 |
| OpName %main "main" ; id %4 |
| OpName %gl_PerVertex "gl_PerVertex" ; id %11 |
| OpMemberName %gl_PerVertex 0 "gl_Position" |
| OpMemberName %gl_PerVertex 1 "gl_PointSize" |
| OpMemberName %gl_PerVertex 2 "gl_ClipDistance" |
| OpMemberName %gl_PerVertex 3 "gl_CullDistance" |
| OpName %_ "" ; id %13 |
| |
| ; Annotations |
| OpMemberDecorate %gl_PerVertex 0 BuiltIn Position |
| OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize |
| OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance |
| OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance |
| OpDecorate %gl_PerVertex Block |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %v4float = OpTypeVector %float 4 |
| %uint = OpTypeInt 32 0 |
| %uint_1 = OpConstant %uint 1 |
| %_arr_float_uint_1 = OpTypeArray %float %uint_1 |
| %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 |
| %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex |
| %_ = OpVariable %_ptr_Output_gl_PerVertex Output |
| %int = OpTypeInt 32 1 |
| %int_0 = OpConstant %int 0 |
| %float_1 = OpConstant %float 1 |
| %17 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 |
| %_ptr_Output_v4float = OpTypePointer Output %v4float |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %19 = OpAccessChain %_ptr_Output_v4float %_ %int_0 |
| OpStore %19 %17 |
| OpReturn |
| OpFunctionEnd)"; |
| |
| std::vector<uint32_t> tesc_spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, tesc_src, tesc_spv); |
| std::vector<uint32_t> tese_spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, tese_src, tese_spv); |
| |
| VkShaderCreateInfoEXT createInfos[2]; |
| createInfos[0] = vku::InitStructHelper(); |
| createInfos[0].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[0].stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; |
| createInfos[0].nextStage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| createInfos[0].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[0].codeSize = tesc_spv.size() * sizeof(tesc_spv[0]); |
| createInfos[0].pCode = tesc_spv.data(); |
| createInfos[0].pName = "main"; |
| createInfos[1] = vku::InitStructHelper(); |
| createInfos[1].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[1].stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| createInfos[1].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[1].codeSize = tese_spv.size() * sizeof(tese_spv[0]); |
| createInfos[1].pCode = tese_spv.data(); |
| createInfos[1].pName = "main"; |
| |
| VkShaderEXT shaders[2]; |
| vk::CreateShadersEXT(m_device->handle(), 2u, createInfos, nullptr, shaders); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MismatchedTessellationOutputPatchSize) { |
| TEST_DESCRIPTION("Create linked tessellation control and evaluation shaders with different output patch sizes."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateShadersEXT-pCreateInfos-08871"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* tesc_src = R"( |
| OpCapability Tessellation |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationControl %main "main" %gl_TessLevelOuter %gl_TessLevelInner |
| OpExecutionMode %main OutputVertices 4 |
| |
| ; Debug Information |
| OpSource GLSL 460 |
| OpName %main "main" ; id %4 |
| OpName %gl_TessLevelOuter "gl_TessLevelOuter" ; id %11 |
| OpName %gl_TessLevelInner "gl_TessLevelInner" ; id %24 |
| |
| ; Annotations |
| OpDecorate %gl_TessLevelOuter Patch |
| OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter |
| OpDecorate %gl_TessLevelInner Patch |
| OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %uint = OpTypeInt 32 0 |
| %uint_4 = OpConstant %uint 4 |
| %_arr_float_uint_4 = OpTypeArray %float %uint_4 |
| %_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4 |
| %gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output |
| %int = OpTypeInt 32 1 |
| %int_0 = OpConstant %int 0 |
| %int_1 = OpConstant %int 1 |
| %int_2 = OpConstant %int 2 |
| %float_1 = OpConstant %float 1 |
| %_ptr_Output_float = OpTypePointer Output %float |
| %uint_2 = OpConstant %uint 2 |
| %_arr_float_uint_2 = OpTypeArray %float %uint_2 |
| %_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2 |
| %gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %18 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2 |
| OpStore %18 %float_1 |
| %19 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1 |
| OpStore %19 %float_1 |
| %20 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0 |
| OpStore %20 %float_1 |
| %25 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0 |
| OpStore %25 %float_1 |
| OpReturn |
| OpFunctionEnd)"; |
| |
| const char* tese_src = R"( |
| OpCapability Tessellation |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationEvaluation %main "main" %_ |
| OpExecutionMode %main Triangles |
| OpExecutionMode %main SpacingFractionalOdd |
| OpExecutionMode %main VertexOrderCw |
| OpExecutionMode %main OutputVertices 3 |
| |
| ; Debug Information |
| OpSource GLSL 460 |
| OpName %main "main" ; id %4 |
| OpName %gl_PerVertex "gl_PerVertex" ; id %11 |
| OpMemberName %gl_PerVertex 0 "gl_Position" |
| OpMemberName %gl_PerVertex 1 "gl_PointSize" |
| OpMemberName %gl_PerVertex 2 "gl_ClipDistance" |
| OpMemberName %gl_PerVertex 3 "gl_CullDistance" |
| OpName %_ "" ; id %13 |
| |
| ; Annotations |
| OpMemberDecorate %gl_PerVertex 0 BuiltIn Position |
| OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize |
| OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance |
| OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance |
| OpDecorate %gl_PerVertex Block |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %v4float = OpTypeVector %float 4 |
| %uint = OpTypeInt 32 0 |
| %uint_1 = OpConstant %uint 1 |
| %_arr_float_uint_1 = OpTypeArray %float %uint_1 |
| %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 |
| %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex |
| %_ = OpVariable %_ptr_Output_gl_PerVertex Output |
| %int = OpTypeInt 32 1 |
| %int_0 = OpConstant %int 0 |
| %float_1 = OpConstant %float 1 |
| %17 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 |
| %_ptr_Output_v4float = OpTypePointer Output %v4float |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %19 = OpAccessChain %_ptr_Output_v4float %_ %int_0 |
| OpStore %19 %17 |
| OpReturn |
| OpFunctionEnd)"; |
| |
| std::vector<uint32_t> tesc_spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, tesc_src, tesc_spv); |
| std::vector<uint32_t> tese_spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, tese_src, tese_spv); |
| |
| VkShaderCreateInfoEXT createInfos[2]; |
| createInfos[0] = vku::InitStructHelper(); |
| createInfos[0].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[0].stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; |
| createInfos[0].nextStage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| createInfos[0].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[0].codeSize = tesc_spv.size() * sizeof(tesc_spv[0]); |
| createInfos[0].pCode = tesc_spv.data(); |
| createInfos[0].pName = "main"; |
| createInfos[1] = vku::InitStructHelper(); |
| createInfos[1].flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| createInfos[1].stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| createInfos[1].codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfos[1].codeSize = tese_spv.size() * sizeof(tese_spv[0]); |
| createInfos[1].pCode = tese_spv.data(); |
| createInfos[1].pName = "main"; |
| |
| VkShaderEXT shaders[2]; |
| vk::CreateShadersEXT(m_device->handle(), 2u, createInfos, nullptr, shaders); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingSubgroupSizeControlFeature) { |
| TEST_DESCRIPTION("Create shader with invalid flags when subgroupSizeControl is not enabled."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-flags-09404"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, kMinimalShaderGlsl); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.flags = VK_SHADER_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT; |
| createInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingComputeFullSubgroups) { |
| TEST_DESCRIPTION("Create shader with invalid flags when computeFullSubgroups is not enabled."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-flags-09405"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| static const char comp_source[] = R"glsl( |
| #version 460 |
| layout(local_size_x = 32) in; |
| void main() {} |
| )glsl"; |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, comp_source); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.flags = VK_SHADER_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT; |
| createInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, CoverageToColorInvalidFormat) { |
| TEST_DESCRIPTION("Use coverage to color with invalid format."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-rasterizerDiscardEnable-09420"); |
| |
| AddRequiredExtensions(VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentMinimalGlsl)); |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| vk::CmdSetCoverageToColorEnableNV(m_commandBuffer->handle(), VK_TRUE); |
| vk::CmdSetCoverageToColorLocationNV(m_commandBuffer->handle(), 0u); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidViewportSwizzleCount) { |
| TEST_DESCRIPTION("Set invalid viewport count for viewport swizzle."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-viewportCount-09421"); |
| |
| AddRequiredExtensions(VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vertShader(*m_device, stages[0], GLSLToSPV(stages[0], kVertexMinimalGlsl)); |
| const vkt::Shader fragShader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentMinimalGlsl)); |
| |
| VkViewport viewports[2] = {{0, 0, static_cast<float>(m_width), static_cast<float>(m_height), 0.0f, 1.0f}, |
| {0, 0, static_cast<float>(m_width), static_cast<float>(m_height), 0.0f, 1.0f}}; |
| VkRect2D scissors[2] = {{{0, 0}, {m_width, m_height}}, {{0, 0}, {m_width, m_height}}}; |
| VkViewportSwizzleNV viewportSwizzle = { |
| VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV, VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV, |
| VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV, VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV}; |
| |
| m_commandBuffer->begin(); |
| m_commandBuffer->BeginRenderingColor(GetDynamicRenderTarget()); |
| SetDefaultDynamicStates(); |
| vk::CmdSetViewportWithCountEXT(m_commandBuffer->handle(), 2u, viewports); |
| vk::CmdSetScissorWithCountEXT(m_commandBuffer->handle(), 2u, scissors); |
| vk::CmdSetViewportSwizzleNV(m_commandBuffer->handle(), 0u, 1u, &viewportSwizzle); |
| BindVertFragShader(vertShader, fragShader); |
| vk::CmdDraw(m_commandBuffer->handle(), 4, 1, 0, 0); |
| m_commandBuffer->EndRendering(); |
| m_commandBuffer->end(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingTessellationEvaluationSubdivision) { |
| TEST_DESCRIPTION("Create tessellation evaluation shader with missing subdivision."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-codeType-08872"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* tese_src = R"( |
| OpCapability Tessellation |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationEvaluation %main "main" %_ |
| OpExecutionMode %main SpacingFractionalOdd |
| OpExecutionMode %main VertexOrderCw |
| |
| ; Debug Information |
| OpSource GLSL 460 |
| OpName %main "main" ; id %4 |
| OpName %gl_PerVertex "gl_PerVertex" ; id %11 |
| OpMemberName %gl_PerVertex 0 "gl_Position" |
| OpMemberName %gl_PerVertex 1 "gl_PointSize" |
| OpMemberName %gl_PerVertex 2 "gl_ClipDistance" |
| OpMemberName %gl_PerVertex 3 "gl_CullDistance" |
| OpName %_ "" ; id %13 |
| |
| ; Annotations |
| OpMemberDecorate %gl_PerVertex 0 BuiltIn Position |
| OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize |
| OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance |
| OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance |
| OpDecorate %gl_PerVertex Block |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %v4float = OpTypeVector %float 4 |
| %uint = OpTypeInt 32 0 |
| %uint_1 = OpConstant %uint 1 |
| %_arr_float_uint_1 = OpTypeArray %float %uint_1 |
| %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 |
| %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex |
| %_ = OpVariable %_ptr_Output_gl_PerVertex Output |
| %int = OpTypeInt 32 1 |
| %int_0 = OpConstant %int 0 |
| %float_1 = OpConstant %float 1 |
| %17 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 |
| %_ptr_Output_v4float = OpTypePointer Output %v4float |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %19 = OpAccessChain %_ptr_Output_v4float %_ %int_0 |
| OpStore %19 %17 |
| OpReturn |
| OpFunctionEnd)"; |
| |
| std::vector<uint32_t> spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, tese_src, spv); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingTessellationEvaluationOrientation) { |
| TEST_DESCRIPTION("Create tessellation evaluation shader with missing orientation."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-codeType-08873"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* tese_src = R"( |
| OpCapability Tessellation |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationEvaluation %main "main" %_ |
| OpExecutionMode %main Triangles |
| OpExecutionMode %main SpacingFractionalOdd |
| |
| ; Debug Information |
| OpSource GLSL 460 |
| OpName %main "main" ; id %4 |
| OpName %gl_PerVertex "gl_PerVertex" ; id %11 |
| OpMemberName %gl_PerVertex 0 "gl_Position" |
| OpMemberName %gl_PerVertex 1 "gl_PointSize" |
| OpMemberName %gl_PerVertex 2 "gl_ClipDistance" |
| OpMemberName %gl_PerVertex 3 "gl_CullDistance" |
| OpName %_ "" ; id %13 |
| |
| ; Annotations |
| OpMemberDecorate %gl_PerVertex 0 BuiltIn Position |
| OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize |
| OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance |
| OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance |
| OpDecorate %gl_PerVertex Block |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %v4float = OpTypeVector %float 4 |
| %uint = OpTypeInt 32 0 |
| %uint_1 = OpConstant %uint 1 |
| %_arr_float_uint_1 = OpTypeArray %float %uint_1 |
| %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 |
| %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex |
| %_ = OpVariable %_ptr_Output_gl_PerVertex Output |
| %int = OpTypeInt 32 1 |
| %int_0 = OpConstant %int 0 |
| %float_1 = OpConstant %float 1 |
| %17 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 |
| %_ptr_Output_v4float = OpTypePointer Output %v4float |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %19 = OpAccessChain %_ptr_Output_v4float %_ %int_0 |
| OpStore %19 %17 |
| OpReturn |
| OpFunctionEnd)"; |
| |
| std::vector<uint32_t> spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, tese_src, spv); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingTessellationEvaluationSpacing) { |
| TEST_DESCRIPTION("Create tessellation evaluation shader with missing spacing."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-codeType-08874"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* tese_src = R"( |
| OpCapability Tessellation |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationEvaluation %main "main" %_ |
| OpExecutionMode %main Triangles |
| OpExecutionMode %main VertexOrderCw |
| |
| ; Debug Information |
| OpSource GLSL 460 |
| OpName %main "main" ; id %4 |
| OpName %gl_PerVertex "gl_PerVertex" ; id %11 |
| OpMemberName %gl_PerVertex 0 "gl_Position" |
| OpMemberName %gl_PerVertex 1 "gl_PointSize" |
| OpMemberName %gl_PerVertex 2 "gl_ClipDistance" |
| OpMemberName %gl_PerVertex 3 "gl_CullDistance" |
| OpName %_ "" ; id %13 |
| |
| ; Annotations |
| OpMemberDecorate %gl_PerVertex 0 BuiltIn Position |
| OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize |
| OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance |
| OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance |
| OpDecorate %gl_PerVertex Block |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %v4float = OpTypeVector %float 4 |
| %uint = OpTypeInt 32 0 |
| %uint_1 = OpConstant %uint 1 |
| %_arr_float_uint_1 = OpTypeArray %float %uint_1 |
| %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 |
| %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex |
| %_ = OpVariable %_ptr_Output_gl_PerVertex Output |
| %int = OpTypeInt 32 1 |
| %int_0 = OpConstant %int 0 |
| %float_1 = OpConstant %float 1 |
| %17 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 |
| %_ptr_Output_v4float = OpTypePointer Output %v4float |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %19 = OpAccessChain %_ptr_Output_v4float %_ %int_0 |
| OpStore %19 %17 |
| OpReturn |
| OpFunctionEnd)"; |
| |
| std::vector<uint32_t> spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, tese_src, spv); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingTessellationEvaluationPatchSize) { |
| TEST_DESCRIPTION("Create tessellation evaluation shader with missing patch size."); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-codeType-08875"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* tesc_src = R"( |
| OpCapability Tessellation |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationControl %main "main" %gl_TessLevelOuter %gl_TessLevelInner |
| OpExecutionMode %main Quads |
| |
| ; Debug Information |
| OpSource GLSL 460 |
| OpName %main "main" ; id %4 |
| OpName %gl_TessLevelOuter "gl_TessLevelOuter" ; id %11 |
| OpName %gl_TessLevelInner "gl_TessLevelInner" ; id %24 |
| |
| ; Annotations |
| OpDecorate %gl_TessLevelOuter Patch |
| OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter |
| OpDecorate %gl_TessLevelInner Patch |
| OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %uint = OpTypeInt 32 0 |
| %uint_4 = OpConstant %uint 4 |
| %_arr_float_uint_4 = OpTypeArray %float %uint_4 |
| %_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4 |
| %gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output |
| %int = OpTypeInt 32 1 |
| %int_0 = OpConstant %int 0 |
| %int_1 = OpConstant %int 1 |
| %int_2 = OpConstant %int 2 |
| %float_1 = OpConstant %float 1 |
| %_ptr_Output_float = OpTypePointer Output %float |
| %uint_2 = OpConstant %uint 2 |
| %_arr_float_uint_2 = OpTypeArray %float %uint_2 |
| %_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2 |
| %gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %18 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2 |
| OpStore %18 %float_1 |
| %19 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1 |
| OpStore %19 %float_1 |
| %20 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0 |
| OpStore %20 %float_1 |
| %25 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0 |
| OpStore %25 %float_1 |
| OpReturn |
| OpFunctionEnd)"; |
| |
| std::vector<uint32_t> spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, tesc_src, spv); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, TessellationPatchSize) { |
| TEST_DESCRIPTION("Create tessellation shader with invalid patch size."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| for (uint32_t i = 0; i < 2; ++i) { |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShaderCreateInfoEXT-pCode-08453"); |
| |
| std::string tesc_src = R"( |
| OpCapability Tessellation |
| %1 = OpExtInstImport "GLSL.std.450" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationControl %main "main" %gl_TessLevelOuter %gl_TessLevelInner |
| OpExecutionMode %main OutputVertices )"; |
| tesc_src += i == 0 ? std::string("0") : std::to_string(m_device->phy().limits_.maxTessellationPatchSize + 1u); |
| tesc_src += R"( |
| ; Debug Information |
| OpSource GLSL 460 |
| OpName %main "main" ; id %4 |
| OpName %gl_TessLevelOuter "gl_TessLevelOuter" ; id %11 |
| OpName %gl_TessLevelInner "gl_TessLevelInner" ; id %24 |
| |
| ; Annotations |
| OpDecorate %gl_TessLevelOuter Patch |
| OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter |
| OpDecorate %gl_TessLevelInner Patch |
| OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner |
| |
| ; Types, variables and constants |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %float = OpTypeFloat 32 |
| %uint = OpTypeInt 32 0 |
| %uint_4 = OpConstant %uint 4 |
| %_arr_float_uint_4 = OpTypeArray %float %uint_4 |
| %_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4 |
| %gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output |
| %int = OpTypeInt 32 1 |
| %int_0 = OpConstant %int 0 |
| %int_1 = OpConstant %int 1 |
| %int_2 = OpConstant %int 2 |
| %float_1 = OpConstant %float 1 |
| %_ptr_Output_float = OpTypePointer Output %float |
| %uint_2 = OpConstant %uint 2 |
| %_arr_float_uint_2 = OpTypeArray %float %uint_2 |
| %_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2 |
| %gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %18 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2 |
| OpStore %18 %float_1 |
| %19 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1 |
| OpStore %19 %float_1 |
| %20 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0 |
| OpStore %20 %float_1 |
| %25 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0 |
| OpStore %25 %float_1 |
| OpReturn |
| OpFunctionEnd |
| )"; |
| |
| std::vector<uint32_t> spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, tesc_src.c_str(), spv); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; |
| createInfo.nextStage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = spv.size() * sizeof(spv[0]); |
| createInfo.pCode = spv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(m_device->handle(), 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| } |