| /* |
| * Copyright (c) 2023-2025 Nintendo |
| * Copyright (c) 2023-2025 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 <vulkan/vulkan_core.h> |
| #include "../framework/layer_validation_tests.h" |
| #include "../framework/shader_object_helper.h" |
| #include "../framework/descriptor_helper.h" |
| #include "../framework/render_pass_helper.h" |
| #include "../framework/shader_helper.h" |
| #include "generated/vk_function_pointers.h" |
| #include "shader_templates.h" |
| |
| class NegativeShaderObject : public ShaderObjectTest {}; |
| |
| TEST_F(NegativeShaderObject, SpirvCodeSize) { |
| TEST_DESCRIPTION("Create shader with invalid spirv code size."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT create_info = vku::InitStructHelper(); |
| create_info.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| create_info.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| create_info.codeSize = spv.size() * sizeof(spv[0]) - 2u; |
| create_info.pCode = spv.data(); |
| create_info.pName = "main"; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-codeSize-08735"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, LinkedComputeShader) { |
| TEST_DESCRIPTION("Create compute shader with linked flag."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, kMinimalShaderGlsl); |
| |
| VkShaderCreateInfoEXT create_info = vku::InitStructHelper(); |
| create_info.flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT; |
| create_info.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| create_info.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| create_info.codeSize = spv.size() * sizeof(spv[0]); |
| create_info.pCode = spv.data(); |
| create_info.pName = "main"; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-flags-08412"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidFlags) { |
| AddRequiredExtensions(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::computeFullSubgroups); |
| AddRequiredFeature(vkt::Feature::attachmentFragmentShadingRate); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT create_info = vku::InitStructHelper(); |
| create_info.flags = VK_SHADER_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT; |
| create_info.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| create_info.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| create_info.codeSize = spv.size() * sizeof(spv[0]); |
| create_info.pCode = spv.data(); |
| create_info.pName = "main"; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-flags-08992"); |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-flags-08485"); |
| create_info.flags = VK_SHADER_CREATE_DISPATCH_BASE_BIT_EXT; |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-flags-08486"); |
| create_info.flags = VK_SHADER_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_EXT; |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidMeshShaderExtFlags) { |
| TEST_DESCRIPTION("Create mesh shader with invalid flags."); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_1)); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT create_info = vku::InitStructHelper(); |
| create_info.flags = VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT; |
| create_info.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| create_info.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| create_info.codeSize = spv.size() * sizeof(spv[0]); |
| create_info.pCode = spv.data(); |
| create_info.pName = "main"; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-flags-08414"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, VertexNextStage) { |
| TEST_DESCRIPTION("Create vertex shader with invalid next stage."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT create_info = vku::InitStructHelper(); |
| create_info.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| create_info.nextStage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| create_info.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| create_info.codeSize = spv.size() * sizeof(spv[0]); |
| create_info.pCode = spv.data(); |
| create_info.pName = "main"; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-nextStage-08427"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, TessellationControlNextStage) { |
| TEST_DESCRIPTION("Create tessellation control shader with invalid next stage."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, kTessellationControlMinimalGlsl); |
| |
| VkShaderCreateInfoEXT create_info = vku::InitStructHelper(); |
| create_info.stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; |
| create_info.nextStage = VK_SHADER_STAGE_GEOMETRY_BIT; |
| create_info.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| create_info.codeSize = spv.size() * sizeof(spv[0]); |
| create_info.pCode = spv.data(); |
| create_info.pName = "main"; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-nextStage-08430"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, TessellationEvaluationNextStage) { |
| TEST_DESCRIPTION("Create tessellation evaluation shader with invalid next stage."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, kTessellationEvalMinimalGlsl); |
| |
| VkShaderCreateInfoEXT create_info = vku::InitStructHelper(); |
| create_info.stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| create_info.nextStage = VK_SHADER_STAGE_VERTEX_BIT; |
| create_info.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| create_info.codeSize = spv.size() * sizeof(spv[0]); |
| create_info.pCode = spv.data(); |
| create_info.pName = "main"; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-nextStage-08431"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, GeometryNextStage) { |
| TEST_DESCRIPTION("Create geometry shader with invalid next stage."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_GEOMETRY_BIT, kGeometryMinimalGlsl); |
| |
| VkShaderCreateInfoEXT create_info = vku::InitStructHelper(); |
| create_info.stage = VK_SHADER_STAGE_GEOMETRY_BIT; |
| create_info.nextStage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; |
| create_info.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| create_info.codeSize = spv.size() * sizeof(spv[0]); |
| create_info.pCode = spv.data(); |
| create_info.pName = "main"; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-nextStage-08433"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, FragmentNextStage) { |
| TEST_DESCRIPTION("Create fragment shader with invalid next stage."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| VkShaderCreateInfoEXT create_info = vku::InitStructHelper(); |
| create_info.stage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| create_info.nextStage = VK_SHADER_STAGE_VERTEX_BIT; |
| create_info.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| create_info.codeSize = spv.size() * sizeof(spv[0]); |
| create_info.pCode = spv.data(); |
| create_info.pName = "main"; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-nextStage-08434"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, TaskNextStage) { |
| TEST_DESCRIPTION("Create task shader with invalid next stage."); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_2)); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_TASK_BIT_EXT, kTaskMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| |
| VkShaderCreateInfoEXT create_info = vku::InitStructHelper(); |
| create_info.stage = VK_SHADER_STAGE_TASK_BIT_EXT; |
| create_info.nextStage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| create_info.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| create_info.codeSize = spv.size() * sizeof(spv[0]); |
| create_info.pCode = spv.data(); |
| create_info.pName = "main"; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-nextStage-08435"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MeshNextStage) { |
| TEST_DESCRIPTION("Create mesh shader with invalid next stage."); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_2)); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| |
| VkShaderCreateInfoEXT create_info = vku::InitStructHelper(); |
| create_info.stage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| create_info.nextStage = VK_SHADER_STAGE_COMPUTE_BIT; |
| create_info.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| create_info.codeSize = spv.size() * sizeof(spv[0]); |
| create_info.pCode = spv.data(); |
| create_info.pName = "main"; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-nextStage-08436"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, TaskNVNextStage) { |
| TEST_DESCRIPTION("Create task shader with invalid next stage."); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_2)); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_TASK_BIT_NV, kTaskMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| |
| VkShaderCreateInfoEXT create_info = vku::InitStructHelper(); |
| create_info.stage = VK_SHADER_STAGE_TASK_BIT_NV; |
| create_info.nextStage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| create_info.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| create_info.codeSize = spv.size() * sizeof(spv[0]); |
| create_info.pCode = spv.data(); |
| create_info.pName = "main"; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-nextStage-08435"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MeshNVNextStage) { |
| TEST_DESCRIPTION("Create mesh shader with invalid next stage."); |
| |
| 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 create_info = vku::InitStructHelper(); |
| create_info.stage = VK_SHADER_STAGE_MESH_BIT_NV; |
| create_info.nextStage = VK_SHADER_STAGE_COMPUTE_BIT; |
| create_info.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| create_info.codeSize = spv.size() * sizeof(spv[0]); |
| create_info.pCode = spv.data(); |
| create_info.pName = "main"; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-nextStage-08436"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, BinaryCodeAlignment) { |
| TEST_DESCRIPTION("Create binary shader with invalid binary code alignment."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| std::vector<uint32_t> spv(256); |
| |
| auto ptr = reinterpret_cast<std::uintptr_t>(spv.data()) + sizeof(uint8_t); |
| |
| VkShaderCreateInfoEXT create_info = vku::InitStructHelper(); |
| create_info.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| create_info.codeType = VK_SHADER_CODE_TYPE_BINARY_EXT; |
| create_info.codeSize = spv.size() * sizeof(spv[0]); |
| create_info.pCode = reinterpret_cast<void*>(ptr); |
| create_info.pName = "main"; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-pCode-08492"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, SpirvCodeAlignment) { |
| TEST_DESCRIPTION("Create shader with invalid binary code alignment."); |
| 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 create_info = vku::InitStructHelper(); |
| create_info.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| create_info.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| create_info.codeSize = spv.size() * sizeof(spv[0]); |
| create_info.pCode = reinterpret_cast<void*>(ptr); |
| create_info.pName = "main"; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-pCode-08493"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, SpirvMagic) { |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| uint32_t bad_magic = 4175232508U; |
| VkShaderCreateInfoEXT create_info = vku::InitStructHelper(); |
| create_info.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| create_info.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| create_info.codeSize = sizeof(uint32_t); |
| create_info.pCode = reinterpret_cast<void*>(&bad_magic); |
| create_info.pName = "main"; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-pCode-08738"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidStage) { |
| TEST_DESCRIPTION("Create shader with invalid stage."); |
| |
| 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; |
| m_errorMonitor->SetAllowedFailureMsg("VUID-VkShaderCreateInfoEXT-stage-parameter"); // skip stateless |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-stage-08425"); |
| vk::CreateShadersEXT(*m_device, 1u, &createInfo, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetAllowedFailureMsg("VUID-VkShaderCreateInfoEXT-stage-parameter"); // skip stateless |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-stage-08426"); |
| |
| createInfo.stage = VK_SHADER_STAGE_CLUSTER_CULLING_BIT_HUAWEI; |
| vk::CreateShadersEXT(*m_device, 1u, &createInfo, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, ExceedsSetLimit) { |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| vkt::DescriptorSetLayout ds_layout(*m_device, {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, nullptr}); |
| const uint32_t excess_layouts = 1 + m_device->Physical().limits_.maxBoundDescriptorSets; |
| std::vector<VkDescriptorSetLayout> dsl_array(excess_layouts, ds_layout); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, kMinimalShaderGlsl); |
| VkShaderCreateInfoEXT create_info = vku::InitStructHelper(); |
| create_info.stage = VK_SHADER_STAGE_COMPUTE_BIT; |
| create_info.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| create_info.codeSize = spv.size() * sizeof(spv[0]); |
| create_info.pCode = spv.data(); |
| create_info.pName = "main"; |
| create_info.setLayoutCount = excess_layouts; |
| create_info.pSetLayouts = dsl_array.data(); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-setLayoutCount-12257"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, BindVertexAndTaskShaders) { |
| TEST_DESCRIPTION("Bind vertex and task shaders in the same call."); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_3)); |
| |
| 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); |
| |
| vkt::Shader vert_shader(*m_device, ShaderCreateInfo(vert_spv, VK_SHADER_STAGE_VERTEX_BIT)); |
| vkt::Shader task_shader(*m_device, ShaderCreateInfo(task_spv, VK_SHADER_STAGE_TASK_BIT_EXT)); |
| VkShaderEXT shaders[] = { |
| vert_shader, |
| task_shader, |
| }; |
| |
| VkShaderStageFlagBits stages[] = { |
| VK_SHADER_STAGE_VERTEX_BIT, |
| VK_SHADER_STAGE_TASK_BIT_EXT, |
| }; |
| m_command_buffer.Begin(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindShadersEXT-pShaders-08470"); |
| vk::CmdBindShadersEXT(m_command_buffer, 2u, stages, shaders); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, BindVertexAndMeshShaders) { |
| TEST_DESCRIPTION("Bind vertex and mesh shaders in the same call."); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_3)); |
| |
| 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); |
| |
| vkt::Shader vert_shader(*m_device, ShaderCreateInfo(vert_spv, VK_SHADER_STAGE_VERTEX_BIT)); |
| vkt::Shader mesh_shader(*m_device, ShaderCreateInfo(mesh_spv, VK_SHADER_STAGE_MESH_BIT_EXT)); |
| VkShaderEXT shaders[] = { |
| vert_shader, |
| mesh_shader, |
| }; |
| |
| VkShaderStageFlagBits stages[] = { |
| VK_SHADER_STAGE_VERTEX_BIT, |
| VK_SHADER_STAGE_MESH_BIT_EXT, |
| }; |
| m_command_buffer.Begin(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindShadersEXT-pShaders-08471"); |
| vk::CmdBindShadersEXT(m_command_buffer, 2u, stages, shaders); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.End(); |
| } |
| |
| 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); |
| AddRequiredFeature(vkt::Feature::shaderObject); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| { |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-stage-08419"); |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, kTessellationControlMinimalGlsl); |
| vkt::Shader shader(*m_device, ShaderCreateInfoNoNextStage(spv, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| { |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-stage-08420"); |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_GEOMETRY_BIT, kGeometryMinimalGlsl); |
| vkt::Shader shader(*m_device, ShaderCreateInfoNoNextStage(spv, VK_SHADER_STAGE_GEOMETRY_BIT)); |
| 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->SetDesiredError("VUID-VkShaderCreateInfoEXT-stage-08421"); |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_TASK_BIT_EXT, kTaskMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| vkt::Shader shader(*m_device, ShaderCreateInfo(spv, VK_SHADER_STAGE_TASK_BIT_EXT)); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| { |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-stage-08422"); |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| vkt::Shader shader(*m_device, ShaderCreateInfo(spv, VK_SHADER_STAGE_MESH_BIT_EXT)); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| TEST_F(NegativeShaderObject, ComputeShaderNotSupportedByCommandPool) { |
| TEST_DESCRIPTION("Use compute shaders with unsupported command pool."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const std::optional<uint32_t> transfer_queue_family_index = m_device->TransferOnlyQueueFamily(); |
| if (!transfer_queue_family_index) { |
| GTEST_SKIP() << "No suitable queue found."; |
| } |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, kMinimalShaderGlsl); |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_COMPUTE_BIT); |
| vkt::Shader shader(*m_device, create_info); |
| |
| vkt::CommandPool command_pool(*m_device, transfer_queue_family_index.value()); |
| vkt::CommandBuffer command_buffer(*m_device, command_pool); |
| command_buffer.Begin(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindShadersEXT-pShaders-08476"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindShadersEXT-commandBuffer-cmdpool"); |
| vk::CmdBindShadersEXT(command_buffer, 1u, &create_info.stage, &shader.handle()); |
| m_errorMonitor->VerifyFound(); |
| |
| command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, GraphicsShadersNotSupportedByCommandPool) { |
| TEST_DESCRIPTION("Use graphics shaders with unsupported command pool."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const std::optional<uint32_t> non_graphics_queue_family_index = m_device->QueueFamilyWithoutCapabilities(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 create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_VERTEX_BIT); |
| vkt::Shader shader(*m_device, create_info); |
| |
| vkt::CommandPool command_pool(*m_device, non_graphics_queue_family_index.value()); |
| vkt::CommandBuffer command_buffer(*m_device, command_pool); |
| command_buffer.Begin(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindShadersEXT-pShaders-08477"); |
| // Hit if queue also doesn't support compute |
| m_errorMonitor->SetUnexpectedError("VUID-vkCmdBindShadersEXT-commandBuffer-cmdpool"); |
| vk::CmdBindShadersEXT(command_buffer, 1u, &create_info.stage, &shader.handle()); |
| m_errorMonitor->VerifyFound(); |
| |
| command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, GraphicsMeshShadersNotSupportedByCommandPool) { |
| TEST_DESCRIPTION("Use mesh shaders with unsupported command pool."); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_3)); |
| |
| const std::optional<uint32_t> non_graphics_queue_family_index = m_device->QueueFamilyWithoutCapabilities(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 create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_MESH_BIT_EXT); |
| vkt::Shader shader(*m_device, create_info); |
| |
| vkt::CommandPool command_pool(*m_device, non_graphics_queue_family_index.value()); |
| vkt::CommandBuffer command_buffer(*m_device, command_pool); |
| command_buffer.Begin(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindShadersEXT-pShaders-08478"); |
| // Hit if queue also doesn't support compute |
| m_errorMonitor->SetUnexpectedError("VUID-vkCmdBindShadersEXT-commandBuffer-cmdpool"); |
| vk::CmdBindShadersEXT(command_buffer, 1u, &create_info.stage, &shader.handle()); |
| m_errorMonitor->VerifyFound(); |
| |
| command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, NonUniqueShadersBind) { |
| TEST_DESCRIPTION("Bind multiple shaders with same stage."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_VERTEX_BIT); |
| vkt::Shader shader1(*m_device, create_info); |
| vkt::Shader shader2(*m_device, create_info); |
| |
| VkShaderEXT shaders[] = { |
| shader1, |
| shader2, |
| }; |
| VkShaderStageFlagBits stages[] = { |
| VK_SHADER_STAGE_VERTEX_BIT, |
| VK_SHADER_STAGE_VERTEX_BIT, |
| }; |
| |
| m_command_buffer.Begin(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindShadersEXT-pStages-08463"); |
| vk::CmdBindShadersEXT(m_command_buffer, 2u, stages, shaders); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidShaderStageBind) { |
| TEST_DESCRIPTION("Bind shader with invalid stage."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| vkt::Shader shader(*m_device, ShaderCreateInfo(spv, VK_SHADER_STAGE_VERTEX_BIT)); |
| |
| VkShaderStageFlagBits stage = VK_SHADER_STAGE_ALL_GRAPHICS; |
| |
| m_command_buffer.Begin(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindShadersEXT-pShaders-08469"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindShadersEXT-pStages-08464"); |
| vk::CmdBindShadersEXT(m_command_buffer, 1u, &stage, &shader.handle()); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, GetShaderBinaryDataInvalidPointer) { |
| TEST_DESCRIPTION("Get shader binary data with invalid pointer."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| if (IsPlatformMockICD()) { |
| GTEST_SKIP() << "Test not supported by MockICD, GetShaderBinaryDataEXT not implemented"; |
| } |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| vkt::Shader shader(*m_device, ShaderCreateInfo(spv, VK_SHADER_STAGE_VERTEX_BIT)); |
| |
| size_t dataSize = 0; |
| vk::GetShaderBinaryDataEXT(*m_device, shader, &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); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkGetShaderBinaryDataEXT-None-08499"); |
| vk::GetShaderBinaryDataEXT(*m_device, shader, &dataSize, dataPtr); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, DrawWithNoShadersBound) { |
| TEST_DESCRIPTION("Call vkCmdDraw when there are no shaders or pipeline bound."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| InitDynamicRenderTarget(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08684"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08688"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, DrawWithMissingShaders) { |
| TEST_DESCRIPTION("Draw without setting all of the shader objects."); |
| |
| AddRequiredFeature(vkt::Feature::geometryShader); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08687"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, DrawWithoutBindingMeshShadersWhenEnabled) { |
| TEST_DESCRIPTION("Draw without binding all of the shader objects supported by graphics."); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_1)); |
| |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08689"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08690"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, FlagAttachmentFragmentShadingRate) { |
| TEST_DESCRIPTION("Create shader with invalid flags."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| VkShaderCreateInfoEXT create_info = |
| ShaderCreateInfoFlag(spv, VK_SHADER_STAGE_FRAGMENT_BIT, VK_SHADER_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_EXT); |
| VkShaderEXT shader; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-flags-08487"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, FlagFragmentDensityMap) { |
| TEST_DESCRIPTION("Create shader with invalid flags."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| VkShaderCreateInfoEXT create_info = |
| ShaderCreateInfoFlag(spv, VK_SHADER_STAGE_FRAGMENT_BIT, VK_SHADER_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT); |
| VkShaderEXT shader; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-flags-08489"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingLinkStageBit) { |
| TEST_DESCRIPTION("Create a linked and non-linked shader in the same call."); |
| |
| 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] = ShaderCreateInfoLink(vert_spv, VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT); |
| createInfos[1] = ShaderCreateInfo(frag_spv, VK_SHADER_STAGE_FRAGMENT_BIT); |
| |
| VkShaderEXT shaders[2]; |
| m_errorMonitor->SetDesiredError("VUID-vkCreateShadersEXT-pCreateInfos-08402"); |
| vk::CreateShadersEXT(*m_device, 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."); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_3)); |
| |
| 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] = ShaderCreateInfo(mesh_spv, VK_SHADER_STAGE_MESH_BIT_EXT); |
| createInfos[1] = ShaderCreateInfoLink(frag_spv, VK_SHADER_STAGE_FRAGMENT_BIT); |
| |
| VkShaderEXT shaders[2]; |
| m_errorMonitor->SetDesiredError("VUID-vkCreateShadersEXT-pCreateInfos-08403"); |
| vk::CreateShadersEXT(*m_device, 2u, createInfos, nullptr, shaders); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, LinkedVertexAndMeshStages) { |
| TEST_DESCRIPTION("Attempt to create linked vertex and mesh stages."); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_3)); |
| |
| 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] = ShaderCreateInfoLink(vert_spv, VK_SHADER_STAGE_VERTEX_BIT); |
| createInfos[1] = ShaderCreateInfoLink(mesh_spv, VK_SHADER_STAGE_MESH_BIT_EXT); |
| |
| VkShaderEXT shaders[2]; |
| m_errorMonitor->SetDesiredError("VUID-vkCreateShadersEXT-pCreateInfos-08404"); |
| vk::CreateShadersEXT(*m_device, 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."); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_3)); |
| |
| 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] = ShaderCreateInfoLink(task_spv, VK_SHADER_STAGE_TASK_BIT_EXT, VK_SHADER_STAGE_MESH_BIT_EXT); |
| createInfos[1] = ShaderCreateInfoLink(mesh_spv, VK_SHADER_STAGE_MESH_BIT_EXT); |
| createInfos[1].flags |= VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT; |
| |
| VkShaderEXT shaders[2]; |
| m_errorMonitor->SetDesiredError("VUID-vkCreateShadersEXT-pCreateInfos-08405"); |
| vk::CreateShadersEXT(*m_device, 2u, createInfos, nullptr, shaders); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingNextStage) { |
| TEST_DESCRIPTION("Attempt to linked vertex and fragment shaders with missing nextStage."); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredFeature(vkt::Feature::geometryShader); |
| 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] = ShaderCreateInfoLink(vert_spv, VK_SHADER_STAGE_VERTEX_BIT); |
| createInfos[1] = ShaderCreateInfoLink(frag_spv, VK_SHADER_STAGE_FRAGMENT_BIT); |
| VkShaderEXT shaders[2]; |
| m_errorMonitor->SetDesiredError("VUID-vkCreateShadersEXT-pCreateInfos-08409"); |
| vk::CreateShadersEXT(*m_device, 2u, createInfos, nullptr, shaders); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCreateShadersEXT-pCreateInfos-08409"); |
| createInfos[0].nextStage = VK_SHADER_STAGE_GEOMETRY_BIT; |
| vk::CreateShadersEXT(*m_device, 2u, createInfos, nullptr, shaders); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, SameLinkedStage) { |
| TEST_DESCRIPTION("Create multiple linked shaders with the same stage."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT createInfos[2]; |
| createInfos[0] = ShaderCreateInfoLink(spv, VK_SHADER_STAGE_VERTEX_BIT); |
| createInfos[1] = ShaderCreateInfoLink(spv, VK_SHADER_STAGE_VERTEX_BIT); |
| |
| VkShaderEXT shaders[2]; |
| m_errorMonitor->SetDesiredError("VUID-vkCreateShadersEXT-pCreateInfos-08410"); |
| vk::CreateShadersEXT(*m_device, 2u, createInfos, nullptr, shaders); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, LinkedStagesWithDifferentCodeType) { |
| TEST_DESCRIPTION("Create linked shaders with different code types."); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCreateShadersEXT-pCreateInfos-08411"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| if (IsPlatformMockICD()) { |
| GTEST_SKIP() << "Test not supported by MockICD, GetShaderBinaryDataEXT not implemented"; |
| } |
| |
| 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] = ShaderCreateInfoLink(vert_spv, VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT); |
| createInfos[1] = ShaderCreateInfoLink(frag_spv, VK_SHADER_STAGE_FRAGMENT_BIT); |
| VkShaderEXT shaders[2]; |
| vk::CreateShadersEXT(*m_device, 2u, createInfos, nullptr, shaders); |
| |
| size_t dataSize = 0u; |
| vk::GetShaderBinaryDataEXT(*m_device, shaders[0], &dataSize, nullptr); |
| std::vector<uint8_t> binaryData(dataSize); |
| vk::GetShaderBinaryDataEXT(*m_device, 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, 2u, createInfos, nullptr, shaders); |
| |
| for (uint32_t i = 0; i < 2; ++i) { |
| vk::DestroyShaderEXT(*m_device, shaders[i], nullptr); |
| } |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, UnsupportedNextStage) { |
| TEST_DESCRIPTION("Create shader with unsupported next stage."); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| 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 auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderCreateInfoEXT create_info = |
| ShaderCreateInfoLink(spv, VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT); |
| VkShaderEXT shader; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-nextStage-08428"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| |
| create_info.nextStage = VK_SHADER_STAGE_GEOMETRY_BIT; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-nextStage-08429"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidTessellationControlNextStage) { |
| TEST_DESCRIPTION("Create tessellation control shader with invalid nextStage."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, kTessellationControlMinimalGlsl); |
| VkShaderCreateInfoEXT create_info = |
| ShaderCreateInfoLink(spv, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, VK_SHADER_STAGE_GEOMETRY_BIT); |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-nextStage-08430"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidTessellationEvaluationNextStage) { |
| TEST_DESCRIPTION("Create tessellation evaluation shader with invalid nextStage."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, kTessellationEvalMinimalGlsl); |
| VkShaderCreateInfoEXT create_info = |
| ShaderCreateInfoLink(spv, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT); |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-nextStage-08431"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidGeometryNextStage) { |
| TEST_DESCRIPTION("Create geometry shader with invalid nextStage."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_GEOMETRY_BIT, kGeometryMinimalGlsl); |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfoLink(spv, VK_SHADER_STAGE_GEOMETRY_BIT, VK_SHADER_STAGE_GEOMETRY_BIT); |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-nextStage-08433"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidFragmentNextStage) { |
| TEST_DESCRIPTION("Create fragment shader with invalid nextStage."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfoLink(spv, VK_SHADER_STAGE_FRAGMENT_BIT, VK_SHADER_STAGE_VERTEX_BIT); |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-nextStage-08434"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidTaskNextStage) { |
| TEST_DESCRIPTION("Create task shader with invalid nextStage."); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_1)); |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_TASK_BIT_EXT, kTaskMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfoLink(spv, VK_SHADER_STAGE_TASK_BIT_EXT, VK_SHADER_STAGE_FRAGMENT_BIT); |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-nextStage-08435"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidMeshNextStage) { |
| TEST_DESCRIPTION("Create mesh shader with invalid nextStage."); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_1)); |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfoLink(spv, VK_SHADER_STAGE_MESH_BIT_EXT, VK_SHADER_STAGE_GEOMETRY_BIT); |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-nextStage-08436"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, BindInvalidShaderStage) { |
| TEST_DESCRIPTION("Bind shader with different stage than it was created with."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| const vkt::Shader vert_shader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| |
| VkShaderStageFlagBits stage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| |
| m_command_buffer.Begin(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindShadersEXT-pShaders-08469"); |
| vk::CmdBindShadersEXT(m_command_buffer, 1u, &stage, &vert_shader.handle()); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, DrawWithShadersOutsideRenderPass) { |
| TEST_DESCRIPTION("Draw with shaders outside of a render pass."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-renderpass"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, DrawWithShadersInNonDynamicRenderPass) { |
| TEST_DESCRIPTION("Draw with shaders inside a non-dynamic render pass."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| CreateMinimalShaders(); |
| |
| 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(); |
| |
| vkt::Image image(*m_device, 32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::ImageView image_view = image.CreateView(); |
| vkt::Framebuffer framebuffer(*m_device, rp, 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_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp, framebuffer, 32, 32, 1, &clear_value); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08876"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, IncompatibleDescriptorSet) { |
| TEST_DESCRIPTION("Bind an incompatible descriptor set."); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| OneOffDescriptorSet descriptor_set(m_device, |
| { |
| {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}, |
| }); |
| OneOffDescriptorSet descriptor_set_bad(m_device, |
| { |
| {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}, |
| }); |
| vkt::PipelineLayout pipeline_layout_bad(*m_device, {&descriptor_set_bad.layout_}); |
| |
| const vkt::Shader vert_shader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, kMinimalShaderGlsl, &descriptor_set.layout_.handle()); |
| const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentUniformGlsl, &descriptor_set.layout_.handle()); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout_bad, 0u, 1u, |
| &descriptor_set_bad.set_, 0u, nullptr); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08600"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, DescriptorSetNotBound) { |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* cs_source = R"glsl( |
| #version 450 |
| layout(set = 0, binding = 0) buffer SSBO { uint x; }; |
| void main() { |
| x = 0; |
| } |
| )glsl"; |
| auto cs_spirv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, cs_source); |
| |
| OneOffDescriptorSet descriptor_set(m_device, {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}}); |
| const vkt::Shader comp_shader(*m_device, |
| ShaderCreateInfo(cs_spirv, VK_SHADER_STAGE_COMPUTE_BIT, 1, &descriptor_set.layout_.handle())); |
| m_command_buffer.Begin(); |
| m_command_buffer.BindCompShader(comp_shader); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatch-None-08600"); |
| vk::CmdDispatch(m_command_buffer, 1, 1, 1); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, DescriptorSetBoundRange) { |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* cs_source = R"glsl( |
| #version 450 |
| layout(set = 0, binding = 0) buffer SSBO0 { uint x; }; |
| layout(set = 1, binding = 0) buffer SSBO1 { uint y; }; |
| void main() { |
| x = y; |
| } |
| )glsl"; |
| auto cs_spirv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, cs_source); |
| |
| OneOffDescriptorSet descriptor_set(m_device, {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}}); |
| VkDescriptorSetLayout dsl_handles[2] = {descriptor_set.layout_, descriptor_set.layout_}; |
| const vkt::Shader comp_shader(*m_device, ShaderCreateInfo(cs_spirv, VK_SHADER_STAGE_COMPUTE_BIT, 2, dsl_handles)); |
| |
| vkt::Buffer buffer(*m_device, 32, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); |
| descriptor_set.WriteDescriptorBufferInfo(0, buffer, 0, VK_WHOLE_SIZE, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); |
| descriptor_set.UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BindCompShader(comp_shader); |
| vkt::PipelineLayout pipeline_layout(*m_device, {&descriptor_set.layout_}); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_layout, 0u, 1u, &descriptor_set.set_, 0u, |
| nullptr); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatch-None-08600"); |
| vk::CmdDispatch(m_command_buffer, 1, 1, 1); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, NotSettingViewportAndScissor) { |
| TEST_DESCRIPTION("Draw with shader object without setting viewport and scissor."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-viewportCount-03417"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, DifferentViewportAndScissorCount) { |
| TEST_DESCRIPTION("Draw with shader object with different viewport and scissor count."); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredFeature(vkt::Feature::multiViewport); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| 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_command_buffer, 2u, viewports); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-viewportCount-03419"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidViewportWScaling) { |
| TEST_DESCRIPTION("Draw with shader object with invalid viewport count in vkCmdSetViewportWScaling."); |
| |
| AddRequiredExtensions(VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME); |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredFeature(vkt::Feature::multiViewport); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| 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_command_buffer, 2u, viewports); |
| VkRect2D scissors[2]; |
| scissors[0] = {{0, 0}, {100u, 100u}}; |
| scissors[1] = {{0, 100}, {100u, 100u}}; |
| vk::CmdSetScissorWithCountEXT(m_command_buffer, 2u, scissors); |
| VkViewportWScalingNV viewportWScaling = {1.0f, 1.0f}; |
| vk::CmdSetViewportWScalingEnableNV(m_command_buffer, VK_TRUE); |
| vk::CmdSetViewportWScalingNV(m_command_buffer, 0u, 1u, &viewportWScaling); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08636"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidShadingRatePaletteViewportCount) { |
| TEST_DESCRIPTION("Draw with shader object with invalid viewport count in vkCmdSetViewportShadingRatePaletteNV."); |
| |
| 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); |
| AddRequiredFeature(vkt::Feature::shaderObject); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::shadingRateImage); |
| AddRequiredFeature(vkt::Feature::multiViewport); |
| RETURN_IF_SKIP(Init()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| 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_command_buffer, 2u, viewports); |
| VkRect2D scissors[2]; |
| scissors[0] = {{0, 0}, {100u, 100u}}; |
| scissors[1] = {{0, 100}, {100u, 100u}}; |
| vk::CmdSetScissorWithCountEXT(m_command_buffer, 2u, scissors); |
| VkShadingRatePaletteEntryNV defaultShadingRatePaletteEntry = VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV; |
| VkShadingRatePaletteNV shadingRatePalette; |
| shadingRatePalette.shadingRatePaletteEntryCount = 1u; |
| shadingRatePalette.pShadingRatePaletteEntries = &defaultShadingRatePaletteEntry; |
| vk::CmdSetShadingRateImageEnableNV(m_command_buffer, VK_TRUE); |
| vk::CmdSetViewportShadingRatePaletteNV(m_command_buffer, 0u, 1u, &shadingRatePalette); |
| vk::CmdSetCoarseSampleOrderNV(m_command_buffer, VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV, 0u, nullptr); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08637"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetExclusiveScissorEnableNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetExclusiveScissorEnableNV."); |
| |
| AddRequiredExtensions(VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::exclusiveScissor); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07878"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidExclusiveScissorCount) { |
| TEST_DESCRIPTION("Draw with shader object with invalid viewport count in vkCmdSetExclusiveScissorNV."); |
| |
| AddRequiredExtensions(VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::multiViewport); |
| AddRequiredFeature(vkt::Feature::exclusiveScissor); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| if (!DeviceExtensionSupported(VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME, 2)) { |
| GTEST_SKIP() << "need VK_NV_scissor_exclusive version 2"; |
| } |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| 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_command_buffer, 2u, viewports); |
| VkRect2D scissors[2]; |
| scissors[0] = {{0, 0}, {100u, 100u}}; |
| scissors[1] = {{0, 100}, {100u, 100u}}; |
| vk::CmdSetScissorWithCountEXT(m_command_buffer, 2u, scissors); |
| VkBool32 exclusiveScissorEnable = VK_TRUE; |
| vk::CmdSetExclusiveScissorEnableNV(m_command_buffer, 0u, 1u, &exclusiveScissorEnable); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07879"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetRasterizerDiscardEnable) { |
| TEST_DESCRIPTION("Draw with shaders without setting vkCmdSetRasterizerDiscardEnable."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-04876"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthBiasEnable) { |
| TEST_DESCRIPTION("Draw with shaders without setting vkCmdSetDepthBiasEnable."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-04877"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetLogicOp) { |
| TEST_DESCRIPTION("Draw with shaders without setting vkCmdSetLogicOp."); |
| |
| 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(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_LOGIC_OP_EXT}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| vk::CmdSetLogicOpEnableEXT(m_command_buffer, VK_TRUE); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-logicOp-04878"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, BlendEnabledWithNonBlendableFormat) { |
| TEST_DESCRIPTION("Draw with shader objects with blend enabled for attachment format that does not support blending."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| VkFormatProperties props; |
| vk::GetPhysicalDeviceFormatProperties(m_device->Physical(), 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); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| VkBool32 enabled = VK_TRUE; |
| vk::CmdSetColorBlendEnableEXT(m_command_buffer, 0, 1, &enabled); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-blendEnable-04727"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, RasterizationSamplesMismatch) { |
| TEST_DESCRIPTION("Draw with shader objects with invalid rasterization samples in vkCmdSetRasterizationSamplesEXT()."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| vk::CmdSetRasterizationSamplesEXT(m_command_buffer, VK_SAMPLE_COUNT_2_BIT); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08644"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingColorWriteEnable) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetColorWriteEnableEXT()."); |
| |
| AddRequiredExtensions(VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::colorWriteEnable); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07749"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| 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()); |
| |
| vkt::Image img1(*m_device, m_width, m_height, m_render_target_fmt, |
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| vkt::Image img2(*m_device, m_width, m_height, 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(); |
| CreateMinimalShaders(); |
| |
| 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; |
| |
| VkRenderingInfo renderingInfo = vku::InitStructHelper(); |
| renderingInfo.renderArea = {{0, 0}, {100u, 100u}}; |
| renderingInfo.layerCount = 1u; |
| renderingInfo.colorAttachmentCount = 2u; |
| renderingInfo.pColorAttachments = attachments; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRendering(renderingInfo); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| VkBool32 colorWriteEnable = VK_TRUE; |
| vk::CmdSetColorWriteEnableEXT(m_command_buffer, 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_command_buffer, 1u, 1u, &colorWriteMask); |
| VkBool32 colorBlendEnable = VK_FALSE; |
| vk::CmdSetColorBlendEnableEXT(m_command_buffer, 1u, 1u, &colorBlendEnable); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-attachmentCount-07750"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDiscardRectangleEnableEXT) { |
| TEST_DESCRIPTION("Draw with shaders without setting vkCmdSetDiscardRectangleEnableEXT."); |
| |
| AddRequiredExtensions(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07880"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDiscardRectangleModeEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDiscardRectangleModeEXT()."); |
| |
| AddRequiredExtensions(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| if (!DeviceExtensionSupported(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME, 2)) { |
| GTEST_SKIP() << "need VK_EXT_discard_rectangles version 2"; |
| } |
| InitDynamicRenderTarget(); |
| VkPhysicalDeviceDiscardRectanglePropertiesEXT discard_rectangle_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(discard_rectangle_properties); |
| std::vector<VkRect2D> discard_rectangles(discard_rectangle_properties.maxDiscardRectangles); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetDiscardRectangleEnableEXT(m_command_buffer, VK_TRUE); |
| vk::CmdSetDiscardRectangleEXT(m_command_buffer, 0u, discard_rectangles.size(), discard_rectangles.data()); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07881"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDiscardRectangleEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDiscardRectangleEXT()."); |
| |
| AddRequiredExtensions(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| if (!DeviceExtensionSupported(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME, 2)) { |
| GTEST_SKIP() << "need VK_EXT_discard_rectangles version 2"; |
| } |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetDiscardRectangleEnableEXT(m_command_buffer, VK_TRUE); |
| vk::CmdSetDiscardRectangleModeEXT(m_command_buffer, VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-rasterizerDiscardEnable-09236"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDiscardRectangleMaxDiscardRectangles) { |
| AddRequiredExtensions(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| if (!DeviceExtensionSupported(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME, 2)) { |
| GTEST_SKIP() << "need VK_EXT_discard_rectangles version 2"; |
| } |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| VkPhysicalDeviceDiscardRectanglePropertiesEXT discard_rectangle_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(discard_rectangle_properties); |
| if (discard_rectangle_properties.maxDiscardRectangles < 2) { |
| GTEST_SKIP() << "Need at least maxDiscardRectangles of 2"; |
| } |
| |
| const uint32_t count = discard_rectangle_properties.maxDiscardRectangles - 1; |
| std::vector<VkRect2D> discard_rectangles(count); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetDiscardRectangleEnableEXT(m_command_buffer, VK_TRUE); |
| vk::CmdSetDiscardRectangleModeEXT(m_command_buffer, VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT); |
| vk::CmdSetDiscardRectangleEXT(m_command_buffer, 0u, count, discard_rectangles.data()); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-rasterizerDiscardEnable-09236"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthClampEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDepthClampEnableEXT()."); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredFeature(vkt::Feature::depthClamp); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07620"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetPolygonModeEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetPolygonModeEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_POLYGON_MODE_EXT}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07621"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetRasterizationSamplesEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetRasterizationSamplesEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07622"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetSampleMaskEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetSampleMaskEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_SAMPLE_MASK_EXT}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07623"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetAlphaToCoverageEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetAlphaToCoverageEnableEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07624"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetAlphaToOneEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetAlphaToOneEnableEXT."); |
| |
| AddRequiredFeature(vkt::Feature::alphaToOne); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07625"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetLogicOpEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetLogicOpEnableEXT."); |
| |
| 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(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07626"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetColorBlendEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetColorBlendEnableEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07627"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetColorBlendEnableEXTForActiveAttachment) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetColorBlendEnableEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| VkBool32 enable = VK_TRUE; |
| vk::CmdSetColorBlendEnableEXT(m_command_buffer, 1u, 1u, &enable); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-firstAttachment-07476"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetColorBlendEquationEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetColorBlendEquationEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| VkBool32 colorBlendEnable = VK_TRUE; |
| vk::CmdSetColorBlendEnableEXT(m_command_buffer, 0u, 1u, &colorBlendEnable); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-10864"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetColorBlendEquationEXTActiveAttachments) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetColorBlendEquationEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| VkBool32 colorBlendEnable = VK_TRUE; |
| vk::CmdSetColorBlendEnableEXT(m_command_buffer, 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_command_buffer, 1u, 1u, &colorBlendEquation); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-10864"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetFragmentShadingRateKHR) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetFragmentShadingRateKHR."); |
| |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineFragmentShadingRate); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-pipelineFragmentShadingRate-09238"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetColorWriteMaskEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetColorWriteMaskEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07629"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetColorWriteMaskEXTActiveAttachments) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetColorWriteMaskEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| VkColorComponentFlags colorWriteMask = VK_COLOR_COMPONENT_R_BIT; |
| vk::CmdSetColorWriteMaskEXT(m_command_buffer, 1u, 1u, &colorWriteMask); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-firstAttachment-07478"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetRasterizationStreamEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetRasterizationStreamEXT."); |
| |
| AddRequiredExtensions(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::geometryShader); |
| AddRequiredFeature(vkt::Feature::geometryStreams); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| const vkt::Shader geom_shader(*m_device, VK_SHADER_STAGE_GEOMETRY_BIT, kGeometryMinimalGlsl); |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, geom_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07630"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetConservativeRasterizationModeEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetConservativeRasterizationModeEXT."); |
| |
| AddRequiredExtensions(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07631"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetExtraPrimitiveOverestimationSizeEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetExtraPrimitiveOverestimationSizeEXT."); |
| |
| AddRequiredExtensions(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetConservativeRasterizationModeEXT(m_command_buffer, VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07632"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthClipEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDepthClipEnableEXT."); |
| |
| AddRequiredExtensions(VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::depthClipEnable); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07633"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetSampleLocationsEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetSampleLocationsEnableEXT."); |
| |
| AddRequiredExtensions(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07634"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetProvokingVertexModeEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetProvokingVertexModeEXT."); |
| |
| AddRequiredExtensions(VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07636"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingPolygonModeCmdSetLineRasterizationModeEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetLineRasterizationModeEXT."); |
| |
| AddRequiredExtensions(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME); |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredFeature(vkt::Feature::fillModeNonSolid); |
| AddRequiredFeature(vkt::Feature::stippledRectangularLines); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetPolygonModeEXT(m_command_buffer, VK_POLYGON_MODE_LINE); |
| vk::CmdSetLineStippleEnableEXT(m_command_buffer, VK_FALSE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08666"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingPrimitiveTopologyCmdSetLineRasterizationModeEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetLineRasterizationModeEXT."); |
| |
| AddRequiredExtensions(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::stippledRectangularLines); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetPrimitiveTopologyEXT(m_command_buffer, VK_PRIMITIVE_TOPOLOGY_LINE_LIST); |
| vk::CmdSetLineStippleEnableEXT(m_command_buffer, VK_FALSE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08666"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingPolygonModeCmdSetLineStippleEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetLineStippleEnableEXT."); |
| |
| AddRequiredExtensions(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME); |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredFeature(vkt::Feature::stippledRectangularLines); |
| AddRequiredFeature(vkt::Feature::fillModeNonSolid); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetPolygonModeEXT(m_command_buffer, VK_POLYGON_MODE_LINE); |
| vk::CmdSetLineRasterizationModeEXT(m_command_buffer, VK_LINE_RASTERIZATION_MODE_DEFAULT); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08669"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingPrimitiveTopologyCmdSetLineStippleEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetLineStippleEnableEXT."); |
| |
| AddRequiredExtensions(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::stippledRectangularLines); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetPrimitiveTopologyEXT(m_command_buffer, VK_PRIMITIVE_TOPOLOGY_LINE_LIST); |
| vk::CmdSetLineRasterizationModeEXT(m_command_buffer, VK_LINE_RASTERIZATION_MODE_DEFAULT); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08669"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetLineStippleEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetLineStippleEXT."); |
| |
| AddRequiredExtensions(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::stippledRectangularLines); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetLineStippleEnableEXT(m_command_buffer, VK_TRUE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07849"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthClipNegativeOneToOneEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDepthClipNegativeOneToOneEXT."); |
| |
| AddRequiredExtensions(VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::depthClipControl); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07639"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetViewportWScalingEnableNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetViewportWScalingEnableNV."); |
| |
| AddRequiredExtensions(VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07640"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetViewportWScalingNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetViewportWScalingNV."); |
| |
| AddRequiredExtensions(VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetViewportWScalingEnableNV(m_command_buffer, VK_TRUE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-viewportCount-04138"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetViewportSwizzleNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetViewportSwizzleNV."); |
| |
| AddRequiredExtensions(VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07641"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetCoverageToColorEnableNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetCoverageToColorEnableNV."); |
| |
| AddRequiredExtensions(VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07642"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetCoverageToColorLocationNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetCoverageToColorLocationNV."); |
| |
| AddRequiredExtensions(VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetCoverageToColorEnableNV(m_command_buffer, VK_TRUE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07643"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetCoverageModulationModeNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetCoverageModulationModeNV."); |
| |
| AddRequiredExtensions(VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetCoverageModulationTableEnableNV(m_command_buffer, VK_FALSE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07644"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetCoverageModulationTableEnableNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetCoverageModulationTableEnableNV."); |
| |
| AddRequiredExtensions(VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetCoverageModulationModeNV(m_command_buffer, VK_COVERAGE_MODULATION_MODE_RGBA_NV); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07645"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetCoverageModulationTableNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetCoverageModulationTableNV."); |
| |
| AddRequiredExtensions(VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetCoverageModulationModeNV(m_command_buffer, VK_COVERAGE_MODULATION_MODE_NONE_NV); |
| vk::CmdSetCoverageModulationTableEnableNV(m_command_buffer, VK_TRUE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07646"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetShadingRateImageEnableNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetShadingRateImageEnableNV."); |
| |
| 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); |
| AddRequiredFeature(vkt::Feature::shaderObject); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::shadingRateImage); |
| RETURN_IF_SKIP(Init()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetCoarseSampleOrderNV(m_command_buffer, VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV, 0u, nullptr); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07647"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetViewportShadingRatePaletteNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetViewportShadingRatePaletteNV."); |
| |
| 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); |
| AddRequiredFeature(vkt::Feature::shaderObject); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::shadingRateImage); |
| RETURN_IF_SKIP(Init()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetCoarseSampleOrderNV(m_command_buffer, VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV, 0u, nullptr); |
| vk::CmdSetShadingRateImageEnableNV(m_command_buffer, VK_TRUE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-shadingRateImage-09234"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetCoarseSampleOrderNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetCoarseSampleOrderNV."); |
| |
| 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); |
| AddRequiredFeature(vkt::Feature::shaderObject); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::shadingRateImage); |
| RETURN_IF_SKIP(Init()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetShadingRateImageEnableNV(m_command_buffer, VK_FALSE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-shadingRateImage-09233"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetRepresentativeFragmentTestEnableNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetRepresentativeFragmentTestEnableNV."); |
| |
| AddRequiredExtensions(VK_NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::representativeFragmentTest); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07648"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetCoverageReductionModeNV) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetCoverageReductionModeNV."); |
| |
| AddRequiredExtensions(VK_NV_COVERAGE_REDUCTION_MODE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::coverageReductionMode); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetCoverageModulationModeNV(m_command_buffer, VK_COVERAGE_MODULATION_MODE_NONE_NV); |
| vk::CmdSetCoverageModulationTableEnableNV(m_command_buffer, VK_FALSE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07649"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingVertexShaderBind) { |
| TEST_DESCRIPTION("Draw with shader objects without binding vertex shader."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, |
| GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl)); |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| const VkShaderStageFlagBits stage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| vk::CmdBindShadersEXT(m_command_buffer, 1u, &stage, &frag_shader.handle()); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08684"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingTessellationControlBind) { |
| TEST_DESCRIPTION("Draw with shader objects without binding tessellation control shader."); |
| |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::shaderObject); |
| AddRequiredFeature(vkt::Feature::tessellationShader); |
| RETURN_IF_SKIP(Init()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, |
| VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const VkShaderEXT shaders[] = {m_vert_shader, VK_NULL_HANDLE, m_frag_shader}; |
| vk::CmdBindShadersEXT(m_command_buffer, 3u, stages, shaders); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08685"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingTessellationEvaluationBind) { |
| TEST_DESCRIPTION("Draw with shader objects without binding tessellation evaluation shader."); |
| |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::shaderObject); |
| AddRequiredFeature(vkt::Feature::tessellationShader); |
| RETURN_IF_SKIP(Init()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, |
| VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const VkShaderEXT shaders[] = {m_vert_shader, VK_NULL_HANDLE, m_frag_shader}; |
| vk::CmdBindShadersEXT(m_command_buffer, 3u, stages, shaders); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08686"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingGeometryBind) { |
| TEST_DESCRIPTION("Draw with shader objects without binding geometry shader."); |
| |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::shaderObject); |
| AddRequiredFeature(vkt::Feature::geometryShader); |
| RETURN_IF_SKIP(Init()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08687"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingFragmentShaderBind) { |
| TEST_DESCRIPTION("Draw with shader objects without binding fragment shader."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const auto vs_spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| auto vs_shader_ci = ShaderCreateInfoNoNextStage(vs_spv, VK_SHADER_STAGE_VERTEX_BIT); |
| const vkt::Shader vert_shader(*m_device, vs_shader_ci); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| const VkShaderStageFlagBits stage = VK_SHADER_STAGE_VERTEX_BIT; |
| vk::CmdBindShadersEXT(m_command_buffer, 1u, &stage, &vert_shader.handle()); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08688"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingTaskShaderBind) { |
| TEST_DESCRIPTION("Draw with shader objects without binding task shader."); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_1)); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| { |
| VkShaderStageFlagBits meshStage = VK_SHADER_STAGE_MESH_BIT_EXT; |
| VkShaderEXT nullShader = VK_NULL_HANDLE; |
| vk::CmdBindShadersEXT(m_command_buffer, 1u, &meshStage, &nullShader); |
| } |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08689"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingMeshShaderBind) { |
| TEST_DESCRIPTION("Draw with shader objects without binding mesh shader."); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_1)); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| m_command_buffer.BindMeshShaders({}, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08693"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, VertAndMeshShaderBothBound) { |
| TEST_DESCRIPTION("Draw with both vertex and mesh shader objects bound."); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_3)); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| const auto mesh_spv = GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| VkShaderCreateInfoEXT mesh_create_info = |
| ShaderCreateInfoFlag(mesh_spv, VK_SHADER_STAGE_MESH_BIT_EXT, VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT); |
| const vkt::Shader mesh_shader(*m_device, mesh_create_info); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindMeshShaders(mesh_shader, m_frag_shader); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08693"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08696"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08885"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| 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."); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_3)); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| const vkt::Shader mesh_shader(*m_device, VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindMeshShaders(mesh_shader, frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMeshTasksEXT-None-08694"); |
| vk::CmdDrawMeshTasksEXT(m_command_buffer, 1, 1, 1); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, TaskAndMeshShaderWithNoTaskFlag) { |
| TEST_DESCRIPTION("Draw with a task and a mesh shader that was created with the no task shader flag."); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_3)); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| const vkt::Shader task_shader(*m_device, VK_SHADER_STAGE_TASK_BIT_EXT, kTaskMinimalGlsl); |
| |
| const auto mesh_spv = GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| VkShaderCreateInfoEXT mesh_create_info = |
| ShaderCreateInfoFlag(mesh_spv, VK_SHADER_STAGE_MESH_BIT_EXT, VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT); |
| const vkt::Shader mesh_shader(*m_device, mesh_create_info); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindMeshShaders(task_shader, mesh_shader, frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMeshTasksEXT-None-08695"); |
| vk::CmdDrawMeshTasksEXT(m_command_buffer, 1, 1, 1); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingLinkedShaderBind) { |
| TEST_DESCRIPTION("Draw with not all linked shaders bound."); |
| |
| 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 create_infos[2]; |
| create_infos[0] = ShaderCreateInfoLink(vert_spv, VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT); |
| create_infos[1] = ShaderCreateInfoLink(frag_spv, VK_SHADER_STAGE_FRAGMENT_BIT); |
| VkShaderEXT shaders[2]; |
| vk::CreateShadersEXT(*m_device, 2u, create_infos, nullptr, shaders); |
| |
| const vkt::Shader vert_shader(*m_device, shaders[0]); |
| const vkt::Shader frag_shader(*m_device, shaders[1]); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(vert_shader, {}); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08698"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, BindShaderBetweenLinkedShaders) { |
| TEST_DESCRIPTION("Draw when a shader is bound between linked shaders."); |
| |
| AddRequiredFeature(vkt::Feature::geometryShader); |
| 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 create_infos[2]; |
| create_infos[0] = ShaderCreateInfoLink(vert_spv, VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT); |
| create_infos[1] = ShaderCreateInfoLink(frag_spv, VK_SHADER_STAGE_FRAGMENT_BIT); |
| VkShaderEXT shaders[2]; |
| vk::CreateShadersEXT(*m_device, 2u, create_infos, nullptr, shaders); |
| |
| const vkt::Shader vert_shader(*m_device, shaders[0]); |
| const vkt::Shader geom_shader(*m_device, VK_SHADER_STAGE_GEOMETRY_BIT, kGeometryMinimalGlsl); |
| const vkt::Shader frag_shader(*m_device, shaders[1]); |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(vert_shader, geom_shader, frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08699"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, DifferentShaderPushConstantRangesSizee) { |
| TEST_DESCRIPTION("Draw with shaders that have different push constant ranges."); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| VkPushConstantRange ranges = {VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4}; |
| const vkt::Shader vert_shader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl, nullptr, &ranges); |
| const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08878"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, DifferentShaderPushConstantRanges) { |
| TEST_DESCRIPTION("Draw with shaders that have different push constant ranges."); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| VkPushConstantRange ranges_frag = {VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4}; |
| VkPushConstantRange ranges_vert = {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}; |
| |
| const vkt::Shader vert_shader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl, nullptr, &ranges_vert); |
| const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl, nullptr, &ranges_frag); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08878"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, DifferentShaderDescriptorLayoutsSize) { |
| TEST_DESCRIPTION("Draw with shaders that have different descriptor layouts."); |
| 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 vert_shader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl, &descriptor_set.layout_.handle()); |
| const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0u, 1u, &descriptor_set.set_, 0u, |
| nullptr); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08879"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, DifferentShaderDescriptorLayouts) { |
| TEST_DESCRIPTION("Draw with shaders that have different descriptor layouts."); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| OneOffDescriptorSet descriptor_set_frag(m_device, |
| { |
| {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}, |
| }); |
| OneOffDescriptorSet descriptor_set_vert(m_device, |
| { |
| {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, nullptr}, |
| }); |
| vkt::PipelineLayout pipeline_layout(*m_device, {&descriptor_set_frag.layout_}); |
| |
| const vkt::Shader vert_shader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl, &descriptor_set_frag.layout_.handle()); |
| const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl, |
| &descriptor_set_vert.layout_.handle()); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0u, 1u, &descriptor_set_frag.set_, |
| 0u, nullptr); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08879"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetAttachmentFeedbackLoopEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetAttachmentFeedbackLoopEnableEXT."); |
| |
| AddRequiredExtensions(VK_EXT_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::attachmentFeedbackLoopDynamicState); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08877"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetPrimitiveTopologyEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetPrimitiveTopologyEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07842"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetPatchControlPointsEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetPatchControlPointsEXT."); |
| |
| AddRequiredFeature(vkt::Feature::tessellationShader); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| const vkt::Shader tesc_shader(*m_device, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, kTessellationControlMinimalGlsl); |
| const vkt::Shader tese_shader(*m_device, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, kTessellationEvalMinimalGlsl); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT}, true); |
| m_command_buffer.BindShaders(m_vert_shader, tesc_shader, tese_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-04875"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetTessellationDomainOriginEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetTessellationDomainOriginEXT."); |
| |
| AddRequiredFeature(vkt::Feature::tessellationShader); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| const vkt::Shader tesc_shader(*m_device, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, kTessellationControlMinimalGlsl); |
| const vkt::Shader tese_shader(*m_device, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, kTessellationEvalMinimalGlsl); |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT}); |
| m_command_buffer.BindShaders(m_vert_shader, tesc_shader, tese_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07619"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetPrimitiveRestartEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetPrimitiveRestartEnableEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-04879"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, PrimitiveRestartEnable) { |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| vk::CmdSetPrimitiveRestartEnableEXT(m_command_buffer, VK_TRUE); |
| vk::CmdSetPrimitiveTopologyEXT(m_command_buffer, VK_PRIMITIVE_TOPOLOGY_LINE_LIST); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-09637"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetVertexInput) { |
| AddRequiredExtensions(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::extendedDynamicState); |
| AddRequiredFeature(vkt::Feature::vertexInputDynamicState); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_VERTEX_INPUT_EXT}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-04914"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, DrawWithGraphicsShadersWhenMeshShaderIsBound) { |
| TEST_DESCRIPTION("Draw with graphics shader objects when a mesh shader is bound."); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_3)); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| const auto mesh_spv = GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, kMeshMinimalGlsl, SPV_ENV_VULKAN_1_3); |
| VkShaderCreateInfoEXT mesh_create_info = |
| ShaderCreateInfoFlag(mesh_spv, VK_SHADER_STAGE_MESH_BIT_EXT, VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT); |
| const vkt::Shader mesh_shader(*m_device, mesh_create_info); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindMeshShaders(mesh_shader, frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08885"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingPolygonLineCmdSetLineWidthEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetLineWidthEXT when polygon mode is line."); |
| |
| AddRequiredFeature(vkt::Feature::fillModeNonSolid); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_LINE_WIDTH}); |
| vk::CmdSetPolygonModeEXT(m_command_buffer, VK_POLYGON_MODE_LINE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08617"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingPrimitiveTopologyLineCmdSetLineWidthEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetLineWidthEXT when primitive topology is line."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_LINE_WIDTH}); |
| vk::CmdSetPrimitiveTopologyEXT(m_command_buffer, VK_PRIMITIVE_TOPOLOGY_LINE_LIST); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08617"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthBiasEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDepthBiasEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_DEPTH_BIAS}); |
| vk::CmdSetDepthBiasEnableEXT(m_command_buffer, VK_TRUE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07834"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetBlendConstantsEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetBlendConstantsEXT."); |
| AddRequiredExtensions(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({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_command_buffer, 0u, 1u, &colorBlendEquation); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| VkBool32 color_blend_enable = VK_TRUE; |
| vk::CmdSetColorBlendEnableEXT(m_command_buffer, 0u, 1u, &color_blend_enable); |
| VkColorBlendAdvancedEXT color_blend_advanced; |
| color_blend_advanced.advancedBlendOp = VK_BLEND_OP_ADD; |
| color_blend_advanced.srcPremultiplied = VK_FALSE; |
| color_blend_advanced.dstPremultiplied = VK_FALSE; |
| color_blend_advanced.blendOverlap = VK_BLEND_OVERLAP_UNCORRELATED_EXT; |
| color_blend_advanced.clampResults = VK_FALSE; |
| vk::CmdSetColorBlendAdvancedEXT(m_command_buffer, 0u, 1u, &color_blend_advanced); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07835"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthBoundsEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDepthBoundsEXT."); |
| |
| AddRequiredFeature(vkt::Feature::depthBounds); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_DEPTH_BOUNDS}); |
| vk::CmdSetDepthBoundsTestEnableEXT(m_command_buffer, VK_TRUE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07836"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetStencilCompareMaskEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetStencilCompareMaskEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK}); |
| vk::CmdSetStencilTestEnableEXT(m_command_buffer, VK_TRUE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07837"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetStencilWriteMaskEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetStencilWriteMaskEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_STENCIL_WRITE_MASK}); |
| vk::CmdSetStencilTestEnableEXT(m_command_buffer, VK_TRUE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07838"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetStencilReferenceEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetStencilReferenceEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_STENCIL_REFERENCE}); |
| vk::CmdSetStencilTestEnableEXT(m_command_buffer, VK_TRUE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07839"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetSampleLocationsEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetSampleLocationsEXT."); |
| |
| AddRequiredExtensions(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT}); |
| vk::CmdSetSampleLocationsEnableEXT(m_command_buffer, VK_TRUE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-06666"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetCullModeEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetCullModeEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_CULL_MODE}); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07840"); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetFrontFaceEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetFrontFaceEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_FRONT_FACE}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| vk::CmdSetCullModeEXT(m_command_buffer, VK_CULL_MODE_BACK_BIT); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07841"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthTestEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDepthTestEnableEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07843"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthWriteEnableEXT) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDepthWriteEnableEXT."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE}); |
| vk::CmdSetDepthTestEnableEXT(m_command_buffer, VK_TRUE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07844"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthCompareOp) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDepthCompareOp."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_DEPTH_COMPARE_OP}); |
| vk::CmdSetDepthTestEnableEXT(m_command_buffer, VK_TRUE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07845"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetDepthBoundsTestEnable) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetDepthBoundsTestEnable."); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredFeature(vkt::Feature::depthBounds); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07846"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetStencilTestEnable) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetStencilTestEnable."); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07847"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingCmdSetStencilOp) { |
| TEST_DESCRIPTION("Draw with shader objects without setting vkCmdSetStencilOp."); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_STENCIL_OP}); |
| vk::CmdSetStencilTestEnableEXT(m_command_buffer, VK_TRUE); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-07848"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, ComputeShaderGroupCount) { |
| TEST_DESCRIPTION("Dispatch with group count higher than maxComputeWorkGroupCount."); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| uint32_t x_count_limit = m_device->Physical().limits_.maxComputeWorkGroupCount[0]; |
| uint32_t y_count_limit = m_device->Physical().limits_.maxComputeWorkGroupCount[1]; |
| uint32_t z_count_limit = m_device->Physical().limits_.maxComputeWorkGroupCount[2]; |
| |
| const vkt::Shader comp_shader(*m_device, VK_SHADER_STAGE_COMPUTE_BIT, kMinimalShaderGlsl); |
| |
| m_command_buffer.Begin(); |
| |
| m_command_buffer.BindCompShader(comp_shader); |
| |
| if (x_count_limit != vvl::kU32Max) { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatch-groupCountX-00386"); |
| vk::CmdDispatch(m_command_buffer, x_count_limit + 1u, 1u, 1u); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| if (y_count_limit != vvl::kU32Max) { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatch-groupCountY-00387"); |
| vk::CmdDispatch(m_command_buffer, 1u, y_count_limit + 1u, 1u); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| if (z_count_limit != vvl::kU32Max) { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatch-groupCountZ-00388"); |
| vk::CmdDispatch(m_command_buffer, 1u, 1u, z_count_limit + 1u); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, ComputeShaderMissingPushConst) { |
| TEST_DESCRIPTION("Dispatch with a shader object using push const, but not setting it."); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| VkPushConstantRange push_const_range{VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(int)}; |
| |
| 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_}, {push_const_range}); |
| |
| const vkt::Shader comp_shader(*m_device, VK_SHADER_STAGE_COMPUTE_BIT, kComputeShaderGlsl, &descriptor_set.layout_.handle(), |
| &push_const_range); |
| |
| vkt::Buffer buffer(*m_device, 32, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| descriptor_set.WriteDescriptorBufferInfo(0, buffer, 0, 32, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); |
| descriptor_set.UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_layout, 0u, 1u, &descriptor_set.set_, 0u, |
| nullptr); |
| m_command_buffer.BindCompShader(comp_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatch-maintenance4-08602"); |
| vk::CmdDispatch(m_command_buffer, 1u, 1u, 1u); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, SharedMemoryOverLimit) { |
| TEST_DESCRIPTION("Validate compute shader shared memory does not exceed maxComputeSharedMemorySize"); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const uint32_t max_shared_memory_size = m_device->Physical().limits_.maxComputeSharedMemorySize; |
| const uint32_t max_shared_ints = max_shared_memory_size / 4; |
| |
| std::ostringstream cs_src; |
| // Make sure compute pipeline has a compute shader stage set |
| cs_src << R"glsl( |
| #version 450 |
| shared int a[)glsl"; |
| cs_src << (max_shared_ints + 16); |
| cs_src << R"glsl(]; |
| void main(){ |
| } |
| )glsl"; |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, cs_src.str().c_str()); |
| |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_COMPUTE_BIT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-Workgroup-06530"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidRequireFullSubgroupsFlag) { |
| AddRequiredExtensions(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::computeFullSubgroups); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| VkShaderCreateInfoEXT create_info = |
| ShaderCreateInfoFlag(spv, VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-flags-08992"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, SpecializationMapEntryOffset) { |
| TEST_DESCRIPTION("Create shader with invalid specialization map entry offset."); |
| // Should work without looking at the SPIR-V |
| const VkLayerSettingEXT settings[] = {{OBJECT_LAYER_NAME, "check_shaders", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1, &kVkFalse}}; |
| VkLayerSettingsCreateInfoEXT layer_settings_ci = {VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT, nullptr, 1, settings}; |
| RETURN_IF_SKIP(InitBasicShaderObject(&layer_settings_ci)); |
| 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 map_entry = {}; |
| map_entry.constantID = 0u; |
| map_entry.offset = sizeof(int) * 2; |
| map_entry.size = sizeof(int); |
| |
| VkSpecializationInfo specialization_info = {}; |
| specialization_info.mapEntryCount = 1; |
| specialization_info.pMapEntries = &map_entry; |
| specialization_info.dataSize = sizeof(uint32_t); |
| specialization_info.pData = &data; |
| |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_VERTEX_BIT); |
| create_info.pSpecializationInfo = &specialization_info; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkSpecializationInfo-offset-00773"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, SpecializationMapEntrySize) { |
| TEST_DESCRIPTION("Create shader with specialization map entry out of bounds."); |
| // Should work without looking at the SPIR-V |
| const VkLayerSettingEXT settings[] = {{OBJECT_LAYER_NAME, "check_shaders", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1, &kVkFalse}}; |
| VkLayerSettingsCreateInfoEXT layer_settings_ci = {VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT, nullptr, 1, settings}; |
| RETURN_IF_SKIP(InitBasicShaderObject(&layer_settings_ci)); |
| |
| 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 map_entry = {}; |
| map_entry.constantID = 0u; |
| map_entry.offset = sizeof(int) / 2; |
| map_entry.size = sizeof(int); |
| |
| VkSpecializationInfo specialization_info = {}; |
| specialization_info.mapEntryCount = 1; |
| specialization_info.pMapEntries = &map_entry; |
| specialization_info.dataSize = sizeof(uint32_t); |
| specialization_info.pData = &data; |
| |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_VERTEX_BIT); |
| create_info.pSpecializationInfo = &specialization_info; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkSpecializationInfo-pMapEntries-00774"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, SpecializationMismatch) { |
| TEST_DESCRIPTION("Create shader with invalid spirv code size."); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| 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 map_entry = {}; |
| map_entry.constantID = 0u; |
| map_entry.offset = 0u; |
| map_entry.size = sizeof(int) * 2u; |
| |
| VkSpecializationInfo specialization_info = {}; |
| specialization_info.mapEntryCount = 1; |
| specialization_info.pMapEntries = &map_entry; |
| specialization_info.dataSize = sizeof(uint32_t) * 2; |
| specialization_info.pData = &data; |
| |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_VERTEX_BIT); |
| create_info.pSpecializationInfo = &specialization_info; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkSpecializationMapEntry-constantID-00776"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, SpecializationSameConstantId) { |
| TEST_DESCRIPTION("Create shader with non unique specialization map entries."); |
| // Should work without looking at the SPIR-V |
| const VkLayerSettingEXT settings[] = {{OBJECT_LAYER_NAME, "check_shaders", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1, &kVkFalse}}; |
| VkLayerSettingsCreateInfoEXT layer_settings_ci = {VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT, nullptr, 1, settings}; |
| RETURN_IF_SKIP(InitBasicShaderObject(&layer_settings_ci)); |
| |
| 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 map_entries[2] = {}; |
| map_entries[0].constantID = 0u; |
| map_entries[0].offset = 0u; |
| map_entries[0].size = sizeof(int); |
| map_entries[1].constantID = 0u; |
| map_entries[1].offset = 0u; |
| map_entries[1].size = sizeof(int); |
| |
| VkSpecializationInfo specialization_info = {}; |
| specialization_info.mapEntryCount = 2; |
| specialization_info.pMapEntries = map_entries; |
| specialization_info.dataSize = sizeof(uint32_t); |
| specialization_info.pData = &data; |
| |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_VERTEX_BIT); |
| create_info.pSpecializationInfo = &specialization_info; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkSpecializationInfo-constantID-04911"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingEntrypoint) { |
| TEST_DESCRIPTION("Create shader with invalid spirv code size."); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_VERTEX_BIT); |
| create_info.pName = "invalid"; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-pName-08440"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, 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."); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| // Size an array using a specialization constant of default value equal to 1. |
| const char* fs_src = R"( |
| OpCapability Shader |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint Fragment %main "main" |
| OpExecutionMode %main OriginUpperLeft |
| 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 map_entry = {}; |
| map_entry.constantID = 0u; |
| map_entry.offset = 0u; |
| map_entry.size = sizeof(uint32_t); |
| |
| VkSpecializationInfo specialization_info = {}; |
| specialization_info.mapEntryCount = 1; |
| specialization_info.pMapEntries = &map_entry; |
| specialization_info.dataSize = sizeof(uint32_t); |
| specialization_info.pData = &data; |
| |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfo(fs_spv, VK_SHADER_STAGE_FRAGMENT_BIT); |
| create_info.pSpecializationInfo = &specialization_info; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-pCode-08460"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MinTexelGatherOffset) { |
| TEST_DESCRIPTION("Create shader with texel gather offset lower than minimum."); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| // Size an array using a specialization constant of default value equal to 1. |
| const char* cs_src = R"( |
| OpCapability Shader |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %main "main" |
| OpExecutionMode %main LocalSize 1 1 1 |
| |
| ; 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 create_info = ShaderCreateInfo(cs_spv, VK_SHADER_STAGE_COMPUTE_BIT, 1, &descriptor_set.layout_.handle()); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpImage-06376"); |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpImage-06377"); |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpImage-06377"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, UnsupportedSpirvCapability) { |
| TEST_DESCRIPTION("Create shader with unsupported spirv capability."); |
| 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 |
| OpCapability ClipDistance |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint Vertex %main "main" %_ |
| |
| ; 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 create_info = ShaderCreateInfo(vs_spv, VK_SHADER_STAGE_VERTEX_BIT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-pCode-08740"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, UnsupportedSpirvExtension) { |
| TEST_DESCRIPTION("Create shader with unsupported spirv extension."); |
| 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" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint Vertex %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 create_info = ShaderCreateInfo(vs_spv, VK_SHADER_STAGE_VERTEX_BIT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-pCode-08741"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, SpirvExtensionRequirementsNotMet) { |
| TEST_DESCRIPTION("Create shader with extension requirements not met."); |
| 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_EXT_shader_image_int64" |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %main "main" |
| OpExecutionMode %main LocalSize 1 1 1 |
| %void = OpTypeVoid |
| %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 create_info = ShaderCreateInfo(cs_spv, VK_SHADER_STAGE_COMPUTE_BIT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-pCode-08742"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MemoryModelNotEnabled) { |
| TEST_DESCRIPTION("Create shader with unsupported spirv extension."); |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::shaderObject); |
| AddRequiredFeature(vkt::Feature::vulkanMemoryModel); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| const char* 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_SemanticsRelease); |
| } |
| )glsl"; |
| |
| OneOffDescriptorSet descriptor_set(m_device, {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}}); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, cs_src); |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_COMPUTE_BIT, 1, &descriptor_set.layout_.handle()); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-vulkanMemoryModel-06265"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MaxTransformFeedbackStream) { |
| TEST_DESCRIPTION("Test maxTransformFeedbackStream with shader objects."); |
| 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::ostringstream gsSource; |
| gsSource << R"asm( |
| OpCapability Geometry |
| OpCapability TransformFeedback |
| OpCapability GeometryStreams |
| 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 |
| |
| ; 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 create_info = ShaderCreateInfo(gs_spv, VK_SHADER_STAGE_GEOMETRY_BIT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpEmitStreamVertex-06310"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, TransformFeedbackStride) { |
| TEST_DESCRIPTION("Test maxTransformFeedbackStream with shader objects."); |
| 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::ostringstream vs_src; |
| vs_src << R"asm( |
| OpCapability Shader |
| OpCapability TransformFeedback |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint Vertex %main "main" %tf |
| OpExecutionMode %main Xfb |
| |
| ; Annotations |
| OpDecorate %tf Location 0 |
| OpDecorate %tf XfbBuffer 0 |
| OpDecorate %tf XfbStride )asm"; |
| vs_src << transform_feedback_props.maxTransformFeedbackBufferDataStride + 4; |
| vs_src << 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, vs_src.str().c_str(), vs_spv); |
| |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfo(vs_spv, VK_SHADER_STAGE_VERTEX_BIT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-XfbStride-06313"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MeshOutputVertices) { |
| TEST_DESCRIPTION("Create mesh shader with output vertices higher than max."); |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_3)); |
| |
| VkPhysicalDeviceMeshShaderPropertiesEXT mesh_shader_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(mesh_shader_properties); |
| |
| std::string mesh_src = R"( |
| OpCapability MeshShadingEXT |
| OpExtension "SPV_EXT_mesh_shader" |
| 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 create_info = ShaderCreateInfoLink(spv, VK_SHADER_STAGE_MESH_BIT_EXT, VK_SHADER_STAGE_FRAGMENT_BIT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-MeshEXT-07115"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, Atomics) { |
| TEST_DESCRIPTION("Test atomics with shader objects."); |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredFeature(vkt::Feature::shaderInt64); |
| AddRequiredFeature(vkt::Feature::shaderSharedInt64Atomics); // to allow OpCapability Int64Atomics |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| 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"; |
| |
| OneOffDescriptorSet descriptor_set(m_device, {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}}); |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, cs_src.c_str()); |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_COMPUTE_BIT, 1, &descriptor_set.layout_.handle()); |
| VkShaderEXT shader; |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-None-06278"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, ExtendedTypesDisabled) { |
| TEST_DESCRIPTION("Test VK_KHR_shader_subgroup_extended_types."); |
| 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); |
| |
| 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"; |
| } |
| |
| const char* 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 create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_COMPUTE_BIT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-None-06275"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, ReadShaderClock) { |
| TEST_DESCRIPTION("Test VK_KHR_shader_clock"); |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_KHR_SHADER_CLOCK_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* 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 create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_VERTEX_BIT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-shaderSubgroupClock-06267"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, WriteLessComponent) { |
| TEST_DESCRIPTION("Test writing to image with less components."); |
| 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 |
| )"; |
| |
| OneOffDescriptorSet descriptor_set(m_device, {{0, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}}); |
| std::vector<uint32_t> spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_3, 0, cs_src, spv); |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_COMPUTE_BIT, 1, &descriptor_set.layout_.handle()); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpImageWrite-07112"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, LocalSizeIdExecutionMode) { |
| TEST_DESCRIPTION("Test LocalSizeId spirv execution mode."); |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_4_EXTENSION_NAME); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* cs_src = R"( |
| OpCapability Shader |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %main "main" |
| OpExecutionModeId %main LocalSizeId %uint_1 %uint_1 %uint_1 |
| %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 create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_COMPUTE_BIT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-LocalSizeId-06434"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, ZeroInitializeWorkgroupMemory) { |
| TEST_DESCRIPTION("Test initializing workgroup memory in compute shader."); |
| 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 |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %main "main" |
| OpExecutionMode %main LocalSize 1 1 1 |
| %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 create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_COMPUTE_BIT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-shaderZeroInitializeWorkgroupMemory-06372"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, 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."); |
| 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 |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %4 "main" |
| OpExecutionMode %4 LocalSize 1 1 1 |
| 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 create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_COMPUTE_BIT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-apiVersion-07954"); |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-apiVersion-07955"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MaxSampleMaskWords) { |
| TEST_DESCRIPTION("Test limit of maxSampleMaskWords"); |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::shaderObject); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(Init()); |
| |
| if (m_device->Physical().limits_.maxSampleMaskWords > 1) { |
| GTEST_SKIP() << "maxSampleMaskWords is greater than 1"; |
| } |
| |
| // 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; |
| // } |
| const char* fs_src = R"( |
| OpCapability Shader |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint Fragment %main "main" %gl_SampleMaskIn %uFragColor |
| OpExecutionMode %main OriginUpperLeft |
| OpDecorate %gl_SampleMaskIn Flat |
| OpDecorate %gl_SampleMaskIn BuiltIn SampleMask |
| OpDecorate %uFragColor Location 0 |
| %void = OpTypeVoid |
| %3 = OpTypeFunction %void |
| %int = OpTypeInt 32 1 |
| %_ptr_Function_int = OpTypePointer Function %int |
| %uint = OpTypeInt 32 0 |
| %uint_3 = OpConstant %uint 3 |
| %_arr_int_uint_3 = OpTypeArray %int %uint_3 |
| %_ptr_Input__arr_int_uint_3 = OpTypePointer Input %_arr_int_uint_3 |
| %gl_SampleMaskIn = OpVariable %_ptr_Input__arr_int_uint_3 Input |
| %int_2 = OpConstant %int 2 |
| %_ptr_Input_int = OpTypePointer Input %int |
| %int_0 = OpConstant %int 0 |
| %float = OpTypeFloat 32 |
| %v4float = OpTypeVector %float 4 |
| %_ptr_Output_v4float = OpTypePointer Output %v4float |
| %uFragColor = OpVariable %_ptr_Output_v4float Output |
| %float_0 = OpConstant %float 0 |
| %float_1 = OpConstant %float 1 |
| %28 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1 |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| %x = OpVariable %_ptr_Function_int Function |
| %y = OpVariable %_ptr_Function_int Function |
| %16 = OpAccessChain %_ptr_Input_int %gl_SampleMaskIn %int_2 |
| %17 = OpLoad %int %16 |
| OpStore %x %17 |
| %20 = OpAccessChain %_ptr_Input_int %gl_SampleMaskIn %int_0 |
| %21 = OpLoad %int %20 |
| OpStore %y %21 |
| %29 = OpLoad %int %x |
| %30 = OpConvertSToF %float %29 |
| %31 = OpVectorTimesScalar %v4float %28 %30 |
| %32 = OpLoad %int %y |
| %33 = OpConvertSToF %float %32 |
| %34 = OpVectorTimesScalar %v4float %31 %33 |
| OpStore %uFragColor %34 |
| OpReturn |
| OpFunctionEnd |
| )"; |
| |
| std::vector<uint32_t> spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_3, 0, fs_src, spv); |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_FRAGMENT_BIT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-pCode-08451"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, ConservativeRasterizationPostDepthCoverage) { |
| TEST_DESCRIPTION("Make sure conservativeRasterizationPostDepthCoverage is set if needed."); |
| 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 create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_FRAGMENT_BIT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-FullyCoveredEXT-conservativeRasterizationPostDepthCoverage-04235"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, LocalSizeExceedLimits) { |
| TEST_DESCRIPTION("Create shader where local size exceeds limits."); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| uint32_t x_count_limit = m_device->Physical().limits_.maxComputeWorkGroupCount[0]; |
| |
| std::string cs_src = R"asm( |
| OpCapability Shader |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint GLCompute %main "main" |
| OpExecutionMode %main LocalSize 44 1 1 |
| |
| ; 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 create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_COMPUTE_BIT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-x-06429"); |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-x-06432"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingLineWidthSet) { |
| TEST_DESCRIPTION("Draw with shaders outputing lines but not setting line width dynamic state."); |
| AddRequiredFeature(vkt::Feature::geometryShader); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| const char geom_src[] = R"glsl( |
| #version 460 |
| layout(triangles) in; |
| layout(line_strip, max_vertices=2) out; |
| void main() { |
| gl_Position = vec4(1); |
| EmitVertex(); |
| } |
| )glsl"; |
| |
| const vkt::Shader geom_shader(*m_device, VK_SHADER_STAGE_GEOMETRY_BIT, geom_src); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_LINE_WIDTH}); |
| m_command_buffer.BindShaders(m_vert_shader, geom_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08617"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidViewportCount) { |
| TEST_DESCRIPTION("Draw with a shader that uses PrimitiveShadingRateKHR with invalid viewport count."); |
| AddRequiredExtensions(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineFragmentShadingRate); |
| AddRequiredFeature(vkt::Feature::primitiveFragmentShadingRate); |
| AddRequiredFeature(vkt::Feature::multiViewport); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| VkPhysicalDeviceFragmentShadingRatePropertiesKHR fsr_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(fsr_properties); |
| if (fsr_properties.primitiveFragmentShadingRateWithMultipleViewports) { |
| GTEST_SKIP() << "required primitiveFragmentShadingRateWithMultipleViewports to be unsupported."; |
| } |
| |
| const char* vsSource = R"glsl( |
| #version 450 |
| #extension GL_EXT_fragment_shading_rate : enable |
| void main() { |
| gl_PrimitiveShadingRateEXT = gl_ShadingRateFlag4VerticalPixelsEXT | gl_ShadingRateFlag4HorizontalPixelsEXT; |
| } |
| )glsl"; |
| |
| const vkt::Shader vert_shader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, vsSource); |
| const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| 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_command_buffer, 2u, viewports); |
| VkRect2D scissors[2]; |
| scissors[0] = {{0, 0}, {100u, 100u}}; |
| scissors[1] = {{0, 100}, {100u, 100u}}; |
| vk::CmdSetScissorWithCountEXT(m_command_buffer, 2u, scissors); |
| VkExtent2D fragment_size = {1u, 1u}; |
| VkFragmentShadingRateCombinerOpKHR combiner_ops[2] = {VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, |
| VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR}; |
| vk::CmdSetFragmentShadingRateKHR(m_command_buffer, &fragment_size, combiner_ops); |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-primitiveFragmentShadingRateWithMultipleViewports-08642"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, AlphaToCoverage) { |
| TEST_DESCRIPTION("Draw with fragment shader missing alpha to coverage."); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const char frag_src[] = R"glsl( |
| #version 460 |
| layout(location = 1) out vec4 uFragColor; |
| void main(){ |
| uFragColor = vec4(0,1,0,1); |
| } |
| )glsl"; |
| |
| const vkt::Shader vert_shader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, frag_src); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_LINE_WIDTH}); |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| vk::CmdSetAlphaToCoverageEnableEXT(m_command_buffer, VK_TRUE); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-alphaToCoverageEnable-08920"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingLineRasterizationMode) { |
| TEST_DESCRIPTION("Draw with shaders outputing lines but not setting line rasterization mode dynamic state."); |
| AddRequiredExtensions(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::stippledRectangularLines); |
| AddRequiredFeature(vkt::Feature::geometryShader); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| const char geom_src[] = R"glsl( |
| #version 460 |
| layout(triangles) in; |
| layout(line_strip, max_vertices=2) out; |
| void main() { |
| gl_Position = vec4(1); |
| EmitVertex(); |
| } |
| )glsl"; |
| |
| const vkt::Shader geom_shader(*m_device, VK_SHADER_STAGE_GEOMETRY_BIT, geom_src); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT}); |
| m_command_buffer.BindShaders(m_vert_shader, geom_shader, m_frag_shader); |
| vk::CmdSetLineStippleEnableEXT(m_command_buffer, VK_FALSE); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08666"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingLineStippleEnable) { |
| TEST_DESCRIPTION("Draw with shaders outputing lines but not setting line stipple enable dynamic state."); |
| |
| AddRequiredExtensions(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::stippledRectangularLines); |
| AddRequiredFeature(vkt::Feature::geometryShader); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| const char geom_src[] = R"glsl( |
| #version 460 |
| layout(triangles) in; |
| layout(line_strip, max_vertices=2) out; |
| void main() { |
| gl_Position = vec4(1); |
| EmitVertex(); |
| } |
| )glsl"; |
| |
| const vkt::Shader geom_shader(*m_device, VK_SHADER_STAGE_GEOMETRY_BIT, geom_src); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT}); |
| m_command_buffer.BindShaders(m_vert_shader, geom_shader, m_frag_shader); |
| vk::CmdSetLineRasterizationModeEXT(m_command_buffer, VK_LINE_RASTERIZATION_MODE_DEFAULT); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08669"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidColorWriteMask) { |
| TEST_DESCRIPTION("Draw with invalid color write mask."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| CreateMinimalShaders(); |
| |
| VkFormat format = VK_FORMAT_E5B9G9R9_UFLOAT_PACK32; |
| VkFormatProperties props; |
| vk::GetPhysicalDeviceFormatProperties(m_device->Physical(), 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 image_format_info = vku::InitStructHelper(); |
| image_format_info.format = format; |
| image_format_info.type = VK_IMAGE_TYPE_2D; |
| image_format_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_format_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| VkImageFormatProperties2 image_format_properties = vku::InitStructHelper(); |
| auto res = vk::GetPhysicalDeviceImageFormatProperties2(m_device->Physical(), &image_format_info, &image_format_properties); |
| if (res == VK_ERROR_FORMAT_NOT_SUPPORTED) { |
| GTEST_SKIP() << "image format not supported as color attachment."; |
| } |
| |
| vkt::Image image(*m_device, 256, 256, format, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(image_view, GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| VkColorComponentFlags colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; |
| vk::CmdSetColorWriteMaskEXT(m_command_buffer, 0u, 1u, &colorWriteMask); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-09116"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, Mismatched64BitAttributeType) { |
| TEST_DESCRIPTION("Draw with vertex format not matching vertex input format."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const VkFormat format = VK_FORMAT_R64_SINT; |
| if (!BufferFormatAndFeaturesSupported(Gpu(), format, VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)) { |
| GTEST_SKIP() << "format not supported."; |
| } |
| |
| const char vert_src[] = R"glsl( |
| #version 460 |
| layout(location = 0) in int pos; |
| void main() { |
| gl_Position = vec4(pos); |
| } |
| )glsl"; |
| |
| const vkt::Shader vert_shader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, vert_src); |
| const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| |
| VkVertexInputBindingDescription2EXT vertex_binding_description = vku::InitStructHelper(); |
| vertex_binding_description.binding = 0u; |
| vertex_binding_description.stride = 16u; |
| vertex_binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; |
| vertex_binding_description.divisor = 1u; |
| |
| VkVertexInputAttributeDescription2EXT vertex_attribute_description = vku::InitStructHelper(); |
| vertex_attribute_description.location = 0u; |
| vertex_attribute_description.binding = 0u; |
| vertex_attribute_description.format = format; |
| vertex_attribute_description.offset = 0u; |
| |
| vk::CmdSetVertexInputEXT(m_command_buffer, 1u, &vertex_binding_description, 1u, &vertex_attribute_description); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-format-08936"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, Mismatched32BitAttributeType) { |
| TEST_DESCRIPTION("Draw with vertex format not matching vertex input format."); |
| |
| AddRequiredFeature(vkt::Feature::shaderInt64); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| 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"; |
| |
| const vkt::Shader vert_shader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, vert_src); |
| const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| |
| VkVertexInputBindingDescription2EXT vertex_binding_description = vku::InitStructHelper(); |
| vertex_binding_description.binding = 0u; |
| vertex_binding_description.stride = 16u; |
| vertex_binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; |
| vertex_binding_description.divisor = 1u; |
| |
| VkVertexInputAttributeDescription2EXT vertex_attribute_description = vku::InitStructHelper(); |
| vertex_attribute_description.location = 0u; |
| vertex_attribute_description.binding = 0u; |
| vertex_attribute_description.format = VK_FORMAT_R32_SINT; |
| vertex_attribute_description.offset = 0u; |
| |
| vk::CmdSetVertexInputEXT(m_command_buffer, 1u, &vertex_binding_description, 1u, &vertex_attribute_description); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-format-08937"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MismatchedFormat64Components) { |
| TEST_DESCRIPTION("Draw with vertex format components not matching vertex input format components."); |
| |
| AddRequiredFeature(vkt::Feature::shaderInt64); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const VkFormat format = VK_FORMAT_R64G64B64_SINT; |
| if (!BufferFormatAndFeaturesSupported(Gpu(), format, VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)) { |
| GTEST_SKIP() << "format not supported."; |
| } |
| |
| 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"; |
| |
| const vkt::Shader vert_shader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, vert_src); |
| const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| |
| VkVertexInputBindingDescription2EXT vertex_binding_description = vku::InitStructHelper(); |
| vertex_binding_description.binding = 0u; |
| vertex_binding_description.stride = 24u; |
| vertex_binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; |
| vertex_binding_description.divisor = 1u; |
| |
| VkVertexInputAttributeDescription2EXT vertex_attribute_description = vku::InitStructHelper(); |
| vertex_attribute_description.location = 0u; |
| vertex_attribute_description.binding = 0u; |
| vertex_attribute_description.format = format; |
| vertex_attribute_description.offset = 0u; |
| |
| vk::CmdSetVertexInputEXT(m_command_buffer, 1u, &vertex_binding_description, 1u, &vertex_attribute_description); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-09203"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MismatchedAttributeType) { |
| TEST_DESCRIPTION("Draw with vertex format not matching vertex input format."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const char vert_src[] = R"glsl( |
| #version 460 |
| layout(location=0) in int x; /* attrib provided float */ |
| void main(){ |
| gl_Position = vec4(x); |
| } |
| )glsl"; |
| |
| VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT}; |
| const vkt::Shader vert_shader(*m_device, stages[0], GLSLToSPV(stages[0], vert_src)); |
| const vkt::Shader frag_shader(*m_device, stages[1], GLSLToSPV(stages[1], kFragmentMinimalGlsl)); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| |
| VkVertexInputBindingDescription2EXT binding = vku::InitStructHelper(); |
| binding.stride = 4; |
| binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; |
| binding.divisor = 1; |
| |
| VkVertexInputAttributeDescription2EXT attribute = vku::InitStructHelper(); |
| attribute.format = VK_FORMAT_R32_SFLOAT; |
| |
| vk::CmdSetVertexInputEXT(m_command_buffer, 1, &binding, 1, &attribute); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-Input-08734"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, DescriptorNotUpdated) { |
| TEST_DESCRIPTION("Draw with shaders using a descriptor set that was never updated."); |
| |
| AddRequiredFeature(vkt::Feature::vertexPipelineStoresAndAtomics); |
| 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_}); |
| |
| 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"; |
| |
| 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_, frag_descriptor_set.layout_}; |
| |
| const vkt::Shader vert_shader(*m_device, ShaderCreateInfo(vert_spv, VK_SHADER_STAGE_VERTEX_BIT, 2, descriptor_set_layouts)); |
| const vkt::Shader frag_shader(*m_device, ShaderCreateInfo(frag_spv, VK_SHADER_STAGE_FRAGMENT_BIT, 2, descriptor_set_layouts)); |
| |
| vkt::Buffer buffer(*m_device, 32, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| vert_descriptor_set.WriteDescriptorBufferInfo(0, buffer, 0, 32, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); |
| vert_descriptor_set.UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0u, 1u, &vert_descriptor_set.set_, |
| 0u, nullptr); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 1u, 1u, &frag_descriptor_set.set_, |
| 0u, nullptr); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08114"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, ComputeVaryingAndFullSubgroups) { |
| TEST_DESCRIPTION("Dispatch with compute shader using required full subgroups and allow varying subgroup size flags."); |
| |
| 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 create_info = ShaderCreateInfoFlag( |
| spv, VK_SHADER_STAGE_COMPUTE_BIT, |
| VK_SHADER_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT | VK_SHADER_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-flags-08416"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, 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."); |
| |
| 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 create_info = |
| ShaderCreateInfoFlag(spv, VK_SHADER_STAGE_COMPUTE_BIT, VK_SHADER_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-flags-08417"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, GeometryShaderMaxOutputVertices) { |
| TEST_DESCRIPTION("Create geometry shader with output vertices higher than maximum."); |
| |
| AddRequiredFeature(vkt::Feature::geometryShader); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| std::string geom_src = R"( |
| OpCapability Geometry |
| 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->Physical().limits_.maxGeometryOutputVertices + 1); |
| geom_src += R"( |
| ; 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 create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_GEOMETRY_BIT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-pCode-08454"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, GeometryShaderMaxInvocations) { |
| TEST_DESCRIPTION("Create geometry shader with invocations higher than maximum."); |
| |
| AddRequiredFeature(vkt::Feature::geometryShader); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| std::string geom_src = R"( |
| OpCapability Geometry |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint Geometry %main "main" %_ |
| OpExecutionMode %main Triangles |
| OpExecutionMode %main Invocations )"; |
| geom_src += std::to_string(m_device->Physical().limits_.maxGeometryShaderInvocations + 1); |
| geom_src += R"( |
| OpExecutionMode %main OutputTriangleStrip |
| OpExecutionMode %main OutputVertices 2 |
| |
| ; 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 create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_GEOMETRY_BIT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-pCode-08455"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, 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."); |
| |
| 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_}); |
| |
| 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 vert_shader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl, &descriptor_set.layout_.handle()); |
| |
| const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, frag_src, &descriptor_set.layout_.handle()); |
| |
| vkt::Image image(*m_device, 32, 32, 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); |
| descriptor_set.UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0u, 1u, &descriptor_set.set_, 0u, |
| nullptr); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-magFilter-04553"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, Multiview) { |
| TEST_DESCRIPTION("https://gitlab.khronos.org/vulkan/vulkan/-/issues/4269"); |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredFeature(vkt::Feature::multiview); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| vkt::Image img(*m_device, m_width, m_height, 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; |
| |
| VkRenderingInfo rendering_info = vku::InitStructHelper(); |
| rendering_info.renderArea = {{0, 0}, {100u, 100u}}; |
| rendering_info.layerCount = 1u; |
| rendering_info.colorAttachmentCount = 1u; |
| rendering_info.pColorAttachments = &color_attachment; |
| rendering_info.viewMask = 0x1; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRendering(rendering_info); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-10772"); |
| vk::CmdDraw(m_command_buffer, 3u, 1u, 0u, 0u); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MaxFragmentDualSrcAttachmentsDynamicBlendEnable) { |
| TEST_DESCRIPTION( |
| "Test drawing with dual source blending with too many fragment output attachments, but using dynamic blending."); |
| AddRequiredFeature(vkt::Feature::dualSrcBlend); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const uint32_t count = m_device->Physical().limits_.maxFragmentDualSrcAttachments + 1; |
| if (count != 2) { |
| GTEST_SKIP() << "Test is designed for a maxFragmentDualSrcAttachments of 1"; |
| } |
| |
| const char* fs_src = R"glsl( |
| #version 460 |
| layout(location = 0) out vec4 c0; |
| layout(location = 1) out vec4 c1; |
| void main() { |
| c0 = vec4(0.0f); |
| c1 = vec4(0.0f); |
| } |
| )glsl"; |
| |
| const vkt::Shader vert_shader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, fs_src); |
| |
| vkt::Image img1(*m_device, m_width, m_height, m_render_target_fmt, |
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| vkt::Image img2(*m_device, m_width, m_height, 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; |
| |
| VkRenderingInfo renderingInfo = vku::InitStructHelper(); |
| renderingInfo.renderArea = {{0, 0}, {100u, 100u}}; |
| renderingInfo.layerCount = 1u; |
| renderingInfo.colorAttachmentCount = 2u; |
| renderingInfo.pColorAttachments = attachments; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRendering(renderingInfo); |
| |
| SetDefaultDynamicStatesExclude(); |
| |
| VkBool32 color_blend_enabled[2] = {VK_TRUE, VK_TRUE}; |
| VkColorBlendEquationEXT dual_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}; |
| VkColorBlendEquationEXT normal_color_blend_equation = { |
| VK_BLEND_FACTOR_ONE, 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[2] = {VK_COLOR_COMPONENT_R_BIT, VK_COLOR_COMPONENT_R_BIT}; |
| |
| vk::CmdSetColorBlendEnableEXT(m_command_buffer, 0, 2, color_blend_enabled); |
| vk::CmdSetColorBlendEquationEXT(m_command_buffer, 0, 1, &normal_color_blend_equation); |
| vk::CmdSetColorBlendEquationEXT(m_command_buffer, 1, 1, &dual_color_blend_equation); |
| vk::CmdSetColorWriteMaskEXT(m_command_buffer, 0, 2, color_component_flags); |
| |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-maxFragmentDualSrcAttachments-09239"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, PrimitivesGeneratedQuery) { |
| TEST_DESCRIPTION("Draw with primitives generated query."); |
| |
| 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); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::shaderObject); |
| AddRequiredFeature(vkt::Feature::primitivesGeneratedQuery); |
| |
| RETURN_IF_SKIP(Init()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT, 1); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0); |
| vk::CmdSetRasterizerDiscardEnableEXT(m_command_buffer, VK_TRUE); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-primitivesGeneratedQueryWithRasterizerDiscard-06708"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| vk::CmdEndQuery(m_command_buffer, query_pool, 0); |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, CooperativeMatrix) { |
| TEST_DESCRIPTION("Test cooperative matrix with shader objects"); |
| |
| 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()); |
| |
| VkPhysicalDeviceVulkan11Properties props11 = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(props11); |
| if (props11.subgroupSize > 32) { |
| GTEST_SKIP() << "local_size_x (32) is not a multiple of subgroupSize"; |
| } |
| |
| 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 |
| const char* 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, SPV_ENV_VULKAN_1_3); |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_COMPUTE_BIT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpTypeCooperativeMatrixKHR-10163"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MismatchedTessellationSubdivision) { |
| TEST_DESCRIPTION("Create linked tessellation control and evaluation shaders with different subdivision."); |
| |
| AddRequiredFeature(vkt::Feature::tessellationShader); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* tesc_src = R"( |
| OpCapability Tessellation |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationControl %main "main" %gl_TessLevelOuter %gl_TessLevelInner |
| OpExecutionMode %main OutputVertices 3 |
| OpExecutionMode %main Quads |
| |
| ; 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 |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationEvaluation %main "main" %_ |
| OpExecutionMode %main Triangles |
| OpExecutionMode %main SpacingFractionalOdd |
| OpExecutionMode %main VertexOrderCw |
| |
| ; 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] = |
| ShaderCreateInfoLink(tesc_spv, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT); |
| createInfos[1] = ShaderCreateInfoLink(tese_spv, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT); |
| |
| VkShaderEXT shaders[2]; |
| m_errorMonitor->SetDesiredError("VUID-vkCreateShadersEXT-pCreateInfos-08867"); |
| vk::CreateShadersEXT(*m_device, 2u, createInfos, nullptr, shaders); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MismatchedTessellationOrientation) { |
| TEST_DESCRIPTION("Create linked tessellation control and evaluation shaders with different orientations."); |
| |
| AddRequiredFeature(vkt::Feature::tessellationShader); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* tesc_src = R"( |
| OpCapability Tessellation |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationControl %main "main" %gl_TessLevelOuter %gl_TessLevelInner |
| OpExecutionMode %main OutputVertices 3 |
| OpExecutionMode %main VertexOrderCcw |
| |
| ; 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 |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationEvaluation %main "main" %_ |
| OpExecutionMode %main Triangles |
| OpExecutionMode %main SpacingFractionalOdd |
| OpExecutionMode %main VertexOrderCw |
| |
| ; 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] = |
| ShaderCreateInfoLink(tesc_spv, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT); |
| createInfos[1] = ShaderCreateInfoLink(tese_spv, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT); |
| |
| VkShaderEXT shaders[2]; |
| m_errorMonitor->SetDesiredError("VUID-vkCreateShadersEXT-pCreateInfos-08868"); |
| vk::CreateShadersEXT(*m_device, 2u, createInfos, nullptr, shaders); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MismatchedTessellationSpacing) { |
| TEST_DESCRIPTION("Create linked tessellation control and evaluation shaders with different spacing."); |
| |
| AddRequiredFeature(vkt::Feature::tessellationShader); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* tesc_src = R"( |
| OpCapability Tessellation |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationControl %main "main" %gl_TessLevelOuter %gl_TessLevelInner |
| OpExecutionMode %main OutputVertices 3 |
| OpExecutionMode %main SpacingFractionalEven |
| |
| ; 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 |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationEvaluation %main "main" %_ |
| OpExecutionMode %main Triangles |
| OpExecutionMode %main SpacingFractionalOdd |
| OpExecutionMode %main VertexOrderCw |
| |
| ; 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] = |
| ShaderCreateInfoLink(tesc_spv, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT); |
| createInfos[1] = ShaderCreateInfoLink(tese_spv, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT); |
| |
| VkShaderEXT shaders[2]; |
| m_errorMonitor->SetDesiredError("VUID-vkCreateShadersEXT-pCreateInfos-08870"); |
| vk::CreateShadersEXT(*m_device, 2u, createInfos, nullptr, shaders); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MismatchedTessellationPatchSize) { |
| AddRequiredFeature(vkt::Feature::tessellationShader); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* tesc_src = R"( |
| OpCapability Tessellation |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationControl %main "main" %gl_TessLevelOuter %gl_TessLevelInner |
| OpExecutionMode %main OutputVertices 3 |
| OpExecutionMode %main SpacingFractionalEven |
| |
| ; 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 |
| %_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 |
| OpReturn |
| OpFunctionEnd)"; |
| |
| const char* tese_src = R"( |
| OpCapability Tessellation |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationEvaluation %main "main" %_ |
| OpExecutionMode %main OutputVertices 6 |
| OpExecutionMode %main Triangles |
| OpExecutionMode %main VertexOrderCw |
| |
| ; 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 |
| |
| ; Function main |
| %main = OpFunction %void None %3 |
| %5 = OpLabel |
| 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 create_infos[2]; |
| create_infos[0] = |
| ShaderCreateInfoLink(tesc_spv, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT); |
| create_infos[1] = ShaderCreateInfoLink(tese_spv, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT); |
| |
| VkShaderEXT shaders[2]; |
| m_errorMonitor->SetDesiredError("VUID-vkCreateShadersEXT-pCreateInfos-08871"); |
| vk::CreateShadersEXT(*m_device, 2u, create_infos, nullptr, shaders); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingSubgroupSizeControlFeature) { |
| TEST_DESCRIPTION("Create shader with invalid flags when subgroupSizeControl is not enabled."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, kMinimalShaderGlsl); |
| VkShaderCreateInfoEXT create_info = |
| ShaderCreateInfoFlag(spv, VK_SHADER_STAGE_COMPUTE_BIT, VK_SHADER_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-flags-09404"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingComputeFullSubgroups) { |
| TEST_DESCRIPTION("Create shader with invalid flags when computeFullSubgroups is not enabled."); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| |
| 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); |
| comp_src += R"glsl() in; |
| void main() {} |
| )glsl"; |
| |
| const auto spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, comp_src.c_str()); |
| VkShaderCreateInfoEXT create_info = |
| ShaderCreateInfoFlag(spv, VK_SHADER_STAGE_COMPUTE_BIT, VK_SHADER_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT); |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-flags-09405"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, CoverageToColorInvalidFormat) { |
| TEST_DESCRIPTION("Use coverage to color with invalid format."); |
| |
| AddRequiredExtensions(VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetCoverageToColorEnableNV(m_command_buffer, VK_TRUE); |
| vk::CmdSetCoverageToColorLocationNV(m_command_buffer, 0u); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-rasterizerDiscardEnable-09420"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidViewportSwizzleCount) { |
| TEST_DESCRIPTION("Set invalid viewport count for viewport swizzle."); |
| |
| AddRequiredExtensions(VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::multiViewport); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| 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_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| vk::CmdSetViewportWithCountEXT(m_command_buffer, 2u, viewports); |
| vk::CmdSetScissorWithCountEXT(m_command_buffer, 2u, scissors); |
| vk::CmdSetViewportSwizzleNV(m_command_buffer, 0u, 1u, &viewportSwizzle); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-viewportCount-09421"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingTessellationEvaluationSubdivision) { |
| TEST_DESCRIPTION("Create tessellation evaluation shader with missing subdivision."); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-codeType-08872"); |
| |
| AddRequiredFeature(vkt::Feature::tessellationShader); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* tese_src = R"( |
| OpCapability Tessellation |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationEvaluation %main "main" %_ |
| OpExecutionMode %main SpacingFractionalOdd |
| OpExecutionMode %main VertexOrderCw |
| |
| ; 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 create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT); |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, MissingTessellationControlPatchSize) { |
| AddRequiredFeature(vkt::Feature::tessellationShader); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char* tesc_src = R"( |
| OpCapability Shader |
| OpCapability Tessellation |
| OpMemoryModel Logical GLSL450 |
| OpEntryPoint TessellationControl %main "main" %gl_TessLevelOuter %gl_TessLevelInner |
| |
| ; 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 |
| %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 |
| OpReturn |
| OpFunctionEnd |
| )"; |
| |
| std::vector<uint32_t> spv; |
| ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, tesc_src, spv); |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfo(spv, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT); |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-codeType-12226"); |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, TessellationPatchSize) { |
| TEST_DESCRIPTION("Create tessellation shader with invalid patch size."); |
| |
| AddRequiredFeature(vkt::Feature::tessellationShader); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| for (uint32_t i = 0; i < 2; ++i) { |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-pCode-08453"); |
| |
| std::string tesc_src = R"( |
| OpCapability Tessellation |
| 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->Physical().limits_.maxTessellationPatchSize + 1u); |
| tesc_src += R"( |
| |
| ; 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 create_info = |
| ShaderCreateInfoLink(spv, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT); |
| VkShaderEXT shader; |
| vk::CreateShadersEXT(*m_device, 1u, &create_info, nullptr, &shader); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| TEST_F(NegativeShaderObject, DispatchBaseFlag) { |
| TEST_DESCRIPTION("Compute dispatch without VK_SHADER_CREATE_DISPATCH_BASE_BIT_EXT"); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| const vkt::Shader compShader(*m_device, VK_SHADER_STAGE_COMPUTE_BIT, kMinimalShaderGlsl); |
| m_command_buffer.Begin(); |
| m_command_buffer.BindCompShader(compShader); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchBase-baseGroupX-00427"); |
| vk::CmdDispatchBase(m_command_buffer, 1, 1, 1, 0, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, SetPrimitiveTopologyNonPatch) { |
| AddRequiredFeature(vkt::Feature::tessellationShader); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| const vkt::Shader tesc_shader(*m_device, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, kTessellationControlMinimalGlsl); |
| const vkt::Shader tese_shader(*m_device, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, kTessellationEvalMinimalGlsl); |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, tesc_shader, tese_shader, m_frag_shader); |
| vk::CmdSetPrimitiveTopologyEXT(m_command_buffer, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-primitiveTopology-10286"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, SetPrimitiveTopologyPatch) { |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| vk::CmdSetPrimitiveTopologyEXT(m_command_buffer, VK_PRIMITIVE_TOPOLOGY_PATCH_LIST); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-primitiveTopology-10747"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, SetPointTopologyNoWrite) { |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| vk::CmdSetPrimitiveTopologyEXT(m_command_buffer, VK_PRIMITIVE_TOPOLOGY_POINT_LIST); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-primitiveTopology-10748"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, DescriptorWrongStage) { |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| // wrong stage |
| OneOffDescriptorSet descriptor_set(m_device, {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, nullptr}}); |
| |
| const char comp_src[] = R"glsl( |
| #version 450 |
| layout(local_size_x=16, local_size_x=1, local_size_x=1) in; |
| layout(binding = 0) buffer Output { |
| uint values[16]; |
| } buffer_out; |
| |
| void main() { |
| buffer_out.values[gl_LocalInvocationID.x] = gl_LocalInvocationID.x; |
| } |
| )glsl"; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-codeType-10383"); |
| const vkt::Shader comp_shader(*m_device, VK_SHADER_STAGE_COMPUTE_BIT, GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, comp_src), |
| &descriptor_set.layout_.handle()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, DescriptorWrongStageMultipleBindings) { |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| OneOffDescriptorSet descriptor_set(m_device, {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, |
| {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, nullptr}, |
| {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}}); |
| |
| const char comp_src[] = R"glsl( |
| #version 450 |
| layout(local_size_x=1, local_size_x=1, local_size_x=1) in; |
| layout(set = 0, binding = 0) buffer SSBO_0 { uint a; }; |
| layout(set = 0, binding = 1) buffer SSBO_1 { uint b; }; |
| layout(set = 0, binding = 2) buffer SSBO_2 { uint c; }; |
| void main() { |
| a = b + c; |
| } |
| )glsl"; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-codeType-10383"); |
| const vkt::Shader comp_shader(*m_device, VK_SHADER_STAGE_COMPUTE_BIT, GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, comp_src), |
| &descriptor_set.layout_.handle()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, DescriptorWrongStageMultipleSets) { |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| OneOffDescriptorSet descriptor_set0(m_device, |
| {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}}); |
| OneOffDescriptorSet descriptor_set1(m_device, {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, nullptr}}); |
| OneOffDescriptorSet descriptor_set2(m_device, {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}}); |
| |
| const char comp_src[] = R"glsl( |
| #version 450 |
| layout(local_size_x=1, local_size_x=1, local_size_x=1) in; |
| layout(set = 0, binding = 0) buffer SSBO_0 { uint a; }; |
| layout(set = 1, binding = 0) buffer SSBO_1 { uint b; }; |
| layout(set = 2, binding = 0) buffer SSBO_2 { uint c; }; |
| void main() { |
| a = b + c; |
| } |
| )glsl"; |
| |
| const auto comp_spv = GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, comp_src); |
| VkDescriptorSetLayout dsl[3] = {descriptor_set0.layout_, descriptor_set1.layout_, descriptor_set2.layout_}; |
| VkShaderCreateInfoEXT create_info = ShaderCreateInfo(comp_spv, VK_SHADER_STAGE_COMPUTE_BIT, 3, dsl); |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-codeType-10383"); |
| const vkt::Shader comp_shader(*m_device, create_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, DescriptorNotProvided) { |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char comp_src[] = R"glsl( |
| #version 450 |
| layout(set = 0, binding = 0) buffer SSBO_0 { uint a; }; |
| void main() { |
| a = 0; |
| } |
| )glsl"; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-codeType-10383"); |
| const vkt::Shader comp_shader(*m_device, VK_SHADER_STAGE_COMPUTE_BIT, GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, comp_src)); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, DescriptorTypeMismatch) { |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char comp_src[] = R"glsl( |
| #version 450 |
| layout(set = 0, binding = 0) buffer SSBO_0 { uint a; }; |
| void main() { |
| a = 0; |
| } |
| )glsl"; |
| |
| OneOffDescriptorSet descriptor_set(m_device, {{0, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr}}); |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-codeType-10384"); |
| const vkt::Shader comp_shader(*m_device, VK_SHADER_STAGE_COMPUTE_BIT, GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, comp_src), |
| &descriptor_set.layout_.handle()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, DescriptorCount) { |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char comp_src[] = R"glsl( |
| #version 450 |
| layout(set = 0, binding = 0) buffer SSBO_0 { uint a; } x[3]; |
| void main() { |
| x[2].a = 0; |
| } |
| )glsl"; |
| |
| OneOffDescriptorSet descriptor_set(m_device, {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2, VK_SHADER_STAGE_ALL, nullptr}}); |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-codeType-10385"); |
| const vkt::Shader comp_shader(*m_device, VK_SHADER_STAGE_COMPUTE_BIT, GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, comp_src), |
| &descriptor_set.layout_.handle()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, InlineUniformBlockArray) { |
| AddRequiredExtensions(VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::inlineUniformBlock); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| const char comp_src[] = R"glsl( |
| #version 450 |
| #extension GL_EXT_debug_printf : enable |
| layout(set = 0, binding = 0) buffer SSBO0 { uint ssbo; }; |
| layout(set = 0, binding = 1) uniform InlineUBO { uint x; } inlineArray[4]; |
| void main() { |
| ssbo = inlineArray[0].x; |
| } |
| )glsl"; |
| |
| VkDescriptorPoolInlineUniformBlockCreateInfo pool_inline_info = vku::InitStructHelper(); |
| pool_inline_info.maxInlineUniformBlockBindings = 1; |
| OneOffDescriptorSet descriptor_set(m_device, |
| { |
| {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, |
| {1, VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK, 8, VK_SHADER_STAGE_ALL, nullptr}, |
| }, |
| 0, nullptr, 0, nullptr, &pool_inline_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-codeType-10386"); |
| const vkt::Shader comp_shader(*m_device, VK_SHADER_STAGE_COMPUTE_BIT, GLSLToSPV(VK_SHADER_STAGE_COMPUTE_BIT, comp_src), |
| &descriptor_set.layout_.handle()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, PushConstantNotDeclared) { |
| TEST_DESCRIPTION("Test missing push constant declaration."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitRenderTarget(); |
| |
| const char* vsSource = R"glsl( |
| #version 450 |
| layout(push_constant, std430) uniform foo { float x; } consts; |
| void main(){ |
| gl_Position = vec4(consts.x); |
| } |
| )glsl"; |
| |
| // Set up a push constant range |
| VkPushConstantRange push_constant_range = {}; |
| // Set to the wrong stage to challenge core_validation |
| push_constant_range.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; |
| push_constant_range.size = 4u; |
| |
| const vkt::PipelineLayout pipeline_layout(*m_device, {}, {push_constant_range}); |
| |
| const auto vspv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, vsSource); |
| |
| VkShaderCreateInfoEXT createInfo = vku::InitStructHelper(); |
| createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; |
| createInfo.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT; |
| createInfo.codeSize = vspv.size() * sizeof(vspv[0]); |
| createInfo.pCode = vspv.data(); |
| createInfo.pName = "main"; |
| |
| VkShaderEXT shader; |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-codeType-10064"); |
| vk::CreateShadersEXT(*m_device, 1u, &createInfo, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| |
| createInfo.pushConstantRangeCount = 1u; |
| createInfo.pPushConstantRanges = &push_constant_range; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-codeType-10064"); |
| vk::CreateShadersEXT(*m_device, 1u, &createInfo, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| |
| push_constant_range.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; |
| push_constant_range.offset = 4u; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkShaderCreateInfoEXT-codeType-10065"); |
| vk::CreateShadersEXT(*m_device, 1u, &createInfo, nullptr, &shader); |
| m_errorMonitor->VerifyFound(); |
| |
| push_constant_range.offset = 0u; |
| const vkt::Shader validShader(*m_device, createInfo); |
| } |
| |
| TEST_F(NegativeShaderObject, BindWithoutFeature) { |
| TEST_DESCRIPTION("Use vkCmdBindShadersEXT without enabling shaderObject feature"); |
| |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| m_command_buffer.Begin(); |
| VkShaderStageFlagBits stage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| VkShaderEXT handle = VK_NULL_HANDLE; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindShadersEXT-None-08462"); |
| vk::CmdBindShadersEXT(m_command_buffer, 1u, &stage, &handle); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidRayTracingStage) { |
| TEST_DESCRIPTION("Use vkCmdBindShadersEXT without enabling shaderObject feature"); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| |
| m_command_buffer.Begin(); |
| VkShaderStageFlagBits stage = VK_SHADER_STAGE_RAYGEN_BIT_KHR; |
| VkShaderEXT handle = VK_NULL_HANDLE; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindShadersEXT-pStages-08465"); |
| vk::CmdBindShadersEXT(m_command_buffer, 1u, &stage, &handle); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, TaskMeshShadersDrawWithoutBindingVertex) { |
| TEST_DESCRIPTION("Test drawing using task and mesh shaders without binding anything to vertex stage"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_3)); |
| |
| const char task_src[] = R"glsl( |
| #version 450 |
| #extension GL_EXT_mesh_shader : require |
| layout (local_size_x=1, local_size_y=1, local_size_z=1) in; |
| void main () { |
| EmitMeshTasksEXT(1u, 1u, 1u); |
| } |
| )glsl"; |
| |
| const char mesh_src[] = R"glsl( |
| #version 460 |
| #extension GL_EXT_mesh_shader : require |
| layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; |
| layout(max_vertices = 3) out; |
| layout(max_primitives = 1) out; |
| layout(triangles) out; |
| void main() { |
| SetMeshOutputsEXT(3, 1); |
| gl_MeshVerticesEXT[0].gl_Position = vec4(-1.0, -1.0, 0.0f, 1.0f); |
| gl_MeshVerticesEXT[1].gl_Position = vec4( 3.0, -1.0, 0.0f, 1.0f); |
| gl_MeshVerticesEXT[2].gl_Position = vec4(-1.0, 3.0, 0.0f, 1.0f); |
| gl_PrimitiveTriangleIndicesEXT[0] = uvec3(0, 1, 2); |
| } |
| )glsl"; |
| |
| const char frag_src[] = R"glsl( |
| #version 460 |
| layout(location = 0) out vec4 uFragColor; |
| void main(){ |
| uFragColor = vec4(0.2f, 0.4f, 0.6f, 0.8f); |
| } |
| )glsl"; |
| |
| VkShaderStageFlagBits shader_stages[] = {VK_SHADER_STAGE_TASK_BIT_EXT, VK_SHADER_STAGE_MESH_BIT_EXT, |
| VK_SHADER_STAGE_FRAGMENT_BIT}; |
| |
| const vkt::Shader task_shader(*m_device, shader_stages[0], task_src); |
| const vkt::Shader mesh_shader(*m_device, shader_stages[1], mesh_src); |
| const vkt::Shader frag_shader(*m_device, shader_stages[2], frag_src); |
| |
| VkShaderEXT shaders[3] = {task_shader, mesh_shader, frag_shader}; |
| |
| vkt::Image image(*m_device, m_width, m_height, VK_FORMAT_R32G32B32A32_SFLOAT, |
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT); |
| vkt::ImageView view = image.CreateView(); |
| |
| VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper(); |
| color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| color_attachment.imageView = view; |
| |
| VkRenderingInfo begin_rendering_info = vku::InitStructHelper(); |
| begin_rendering_info.flags = 0u; |
| begin_rendering_info.renderArea.offset = {0, 0}; |
| begin_rendering_info.renderArea.extent = {m_width, m_height}; |
| begin_rendering_info.layerCount = 1u; |
| begin_rendering_info.viewMask = 0x0; |
| begin_rendering_info.colorAttachmentCount = 1u; |
| begin_rendering_info.pColorAttachments = &color_attachment; |
| |
| m_command_buffer.Begin(); |
| vk::CmdBeginRenderingKHR(m_command_buffer, &begin_rendering_info); |
| vk::CmdBindShadersEXT(m_command_buffer, 3u, shader_stages, shaders); |
| SetDefaultDynamicStatesExclude(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMeshTasksEXT-None-08684"); |
| vk::CmdDrawMeshTasksEXT(m_command_buffer, 1, 1, 1); |
| vk::CmdEndRenderingKHR(m_command_buffer); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, DrawMeshTasksWithoutMeshShader) { |
| TEST_DESCRIPTION("Test calling vkCmdDrawMeshTasksEXT when VK_NULL_HANDLE is bound to mesh stage"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_3)); |
| CreateMinimalShaders(); |
| |
| vkt::Image image(*m_device, m_width, m_height, VK_FORMAT_R32G32B32A32_SFLOAT, |
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT); |
| image.SetLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); |
| vkt::ImageView view = image.CreateView(); |
| |
| VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper(); |
| color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| color_attachment.imageView = view; |
| |
| VkRenderingInfo begin_rendering_info = vku::InitStructHelper(); |
| begin_rendering_info.flags = 0u; |
| begin_rendering_info.renderArea.offset = {0, 0}; |
| begin_rendering_info.renderArea.extent = {m_width, m_height}; |
| begin_rendering_info.layerCount = 1u; |
| begin_rendering_info.viewMask = 0x0; |
| begin_rendering_info.colorAttachmentCount = 1u; |
| begin_rendering_info.pColorAttachments = &color_attachment; |
| |
| m_command_buffer.Begin(); |
| vk::CmdBeginRenderingKHR(m_command_buffer, &begin_rendering_info); |
| std::vector<VkShaderStageFlagBits> null_stages = {VK_SHADER_STAGE_TASK_BIT_EXT, VK_SHADER_STAGE_MESH_BIT_EXT}; |
| VkShaderEXT null_shader = VK_NULL_HANDLE; |
| for (const auto stage : null_stages) { |
| vk::CmdBindShadersEXT(m_command_buffer, 1u, &stage, &null_shader); |
| } |
| |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| SetDefaultDynamicStatesExclude(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMeshTasksEXT-pStages-10680"); |
| vk::CmdDrawMeshTasksEXT(m_command_buffer, 1, 1, 1); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndRenderingKHR(m_command_buffer); |
| |
| m_command_buffer.End(); |
| m_default_queue->SubmitAndWait(m_command_buffer); |
| } |
| |
| TEST_F(NegativeShaderObject, VertAndMeshShaderBothNotBound) { |
| TEST_DESCRIPTION("Draw with a neither a vertex or mesh bound"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_3)); |
| InitDynamicRenderTarget(); |
| |
| const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_TASK_BIT_EXT, |
| VK_SHADER_STAGE_MESH_BIT_EXT, |
| 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, |
| VK_NULL_HANDLE, VK_NULL_HANDLE, frag_shader}; |
| vk::CmdBindShadersEXT(m_command_buffer, 7u, stages, shaders); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08693"); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMeshTasksEXT-None-08693"); |
| vk::CmdDrawMeshTasksEXT(m_command_buffer, 1, 1, 1); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, LineRasterization) { |
| AddRequiredExtensions(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::smoothLines); |
| AddRequiredFeature(vkt::Feature::alphaToOne); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitRenderTarget(); |
| CreateMinimalShaders(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude({VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT, VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT}); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| vk::CmdSetAlphaToOneEnableEXT(m_command_buffer, VK_TRUE); |
| vk::CmdSetLineRasterizationModeEXT(m_command_buffer, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH); |
| vk::CmdSetPrimitiveTopologyEXT(m_command_buffer, VK_PRIMITIVE_TOPOLOGY_LINE_LIST); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-10608"); |
| vk::CmdDraw(m_command_buffer, 4u, 1u, 0u, 0u); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, MeshShaderPayloadMemoryOverLimit) { |
| TEST_DESCRIPTION("Validate Mesh shader shared memory limit"); |
| |
| RETURN_IF_SKIP(InitBasicMeshShaderObject(VK_API_VERSION_1_3)); |
| InitRenderTarget(); |
| |
| VkPhysicalDeviceMeshShaderPropertiesEXT mesh_shader_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(mesh_shader_properties); |
| |
| const uint32_t max_mesh_payload_and_shared_memory_size = mesh_shader_properties.maxMeshPayloadAndSharedMemorySize; |
| const uint32_t max_mesh_payload_and_shared_ints = max_mesh_payload_and_shared_memory_size / 4; |
| |
| std::ostringstream mesh_source; |
| mesh_source << R"glsl( |
| #version 460 |
| #extension GL_EXT_mesh_shader : require |
| layout(max_vertices = 3, max_primitives=1) out; |
| layout(triangles) out; |
| struct Task { |
| uint baseID[)glsl"; |
| mesh_source << (max_mesh_payload_and_shared_ints / 2 + 1); |
| mesh_source << R"glsl(]; |
| }; |
| taskPayloadSharedEXT Task IN; |
| shared int a[)glsl"; |
| mesh_source << (max_mesh_payload_and_shared_ints / 2 + 1); |
| mesh_source << R"glsl(]; |
| void main(){} |
| )glsl"; |
| |
| const auto mesh_spv = GLSLToSPV(VK_SHADER_STAGE_MESH_BIT_EXT, mesh_source.str().c_str(), SPV_ENV_VULKAN_1_3); |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-maxMeshPayloadAndSharedMemorySize-08755"); |
| vkt::Shader mesh_shader(*m_device, ShaderCreateInfo(mesh_spv, VK_SHADER_STAGE_MESH_BIT_EXT)); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, DrawMissingNextStage) { |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const auto vs_spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| const vkt::Shader vert_shader(*m_device, ShaderCreateInfoNoNextStage(vs_spv, VK_SHADER_STAGE_VERTEX_BIT)); |
| |
| const auto fs_spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| const vkt::Shader frag_shader(*m_device, ShaderCreateInfoNoNextStage(fs_spv, VK_SHADER_STAGE_FRAGMENT_BIT)); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-nextStage-10745"); |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| vk::CmdDraw(m_command_buffer, 3u, 1u, 0u, 0u); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, DrawWrongNextStage) { |
| AddRequiredFeature(vkt::Feature::tessellationShader); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const auto vs_spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| auto vs_shader_ci = ShaderCreateInfoNoNextStage(vs_spv, VK_SHADER_STAGE_VERTEX_BIT); |
| vs_shader_ci.nextStage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; |
| const vkt::Shader vert_shader(*m_device, vs_shader_ci); |
| |
| const auto fs_spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| const vkt::Shader frag_shader(*m_device, ShaderCreateInfoNoNextStage(fs_spv, VK_SHADER_STAGE_FRAGMENT_BIT)); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-nextStage-10745"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08685"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08686"); |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| vk::CmdDraw(m_command_buffer, 3u, 1u, 0u, 0u); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, NoBoundCompute) { |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| m_command_buffer.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatch-None-10743"); |
| vk::CmdDispatch(m_command_buffer, 1, 1, 1); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, BoundNullCompute) { |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| m_command_buffer.Begin(); |
| |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_COMPUTE_BIT}; |
| const VkShaderEXT shaders[] = {VK_NULL_HANDLE}; |
| vk::CmdBindShadersEXT(m_command_buffer, 1u, stages, shaders); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatch-None-10743"); |
| vk::CmdDispatch(m_command_buffer, 1, 1, 1); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, UnbindCompute) { |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| m_command_buffer.Begin(); |
| |
| const vkt::Shader comp_shader(*m_device, VK_SHADER_STAGE_COMPUTE_BIT, kMinimalShaderGlsl); |
| m_command_buffer.BindCompShader(comp_shader); |
| vk::CmdDispatch(m_command_buffer, 1, 1, 1); |
| |
| const VkShaderStageFlagBits stages[] = {VK_SHADER_STAGE_COMPUTE_BIT}; |
| const VkShaderEXT shaders[] = {VK_NULL_HANDLE}; |
| vk::CmdBindShadersEXT(m_command_buffer, 1u, stages, shaders); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatch-None-10743"); |
| vk::CmdDispatch(m_command_buffer, 1, 1, 1); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, CommandBufferRecording) { |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| VkShaderStageFlagBits stage = VK_SHADER_STAGE_VERTEX_BIT; |
| const vkt::Shader vert_shader(*m_device, stage, kVertexMinimalGlsl); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindShadersEXT-commandBuffer-recording"); |
| vk::CmdBindShadersEXT(m_command_buffer, 1u, &stage, &vert_shader.handle()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeShaderObject, AdvancedBlendMaxAttachments) { |
| TEST_DESCRIPTION("Attempt to use more than maximum attachments in subpass when advanced blend is enabled"); |
| AddRequiredExtensions(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::extendedDynamicState3ColorBlendEnable); |
| AddRequiredFeature(vkt::Feature::extendedDynamicState3ColorBlendAdvanced); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| CreateMinimalShaders(); |
| |
| VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT blend_advanced_props = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(blend_advanced_props); |
| uint32_t attachment_count = blend_advanced_props.advancedBlendMaxColorAttachments + 1; |
| |
| if (attachment_count > m_device->Physical().limits_.maxColorAttachments) { |
| GTEST_SKIP() << "advancedBlendMaxColorAttachments is equal to maxColorAttachments"; |
| } |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.imageType = VK_IMAGE_TYPE_2D; |
| image_ci.format = VK_FORMAT_R8G8B8A8_UNORM; |
| image_ci.extent = {32, 32, 1}; |
| image_ci.mipLevels = 1u; |
| image_ci.arrayLayers = 1u; |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| |
| std::vector<std::unique_ptr<vkt::Image>> images(attachment_count); |
| std::vector<vkt::ImageView> image_views(attachment_count); |
| std::vector<VkRenderingAttachmentInfo> rendering_attachment_info(attachment_count); |
| for (uint32_t i = 0; i < attachment_count; ++i) { |
| images[i] = std::make_unique<vkt::Image>(*m_device, image_ci); |
| image_views[i] = images[i]->CreateView(); |
| rendering_attachment_info[i] = vku::InitStructHelper(); |
| rendering_attachment_info[i].imageView = image_views[i]; |
| rendering_attachment_info[i].imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| rendering_attachment_info[i].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| rendering_attachment_info[i].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| rendering_attachment_info[i].clearValue.color = m_clear_color; |
| } |
| |
| VkRenderingInfo rendering_info = vku::InitStructHelper(); |
| rendering_info.renderArea = {{0, 0}, {32, 32}}; |
| rendering_info.layerCount = 1u; |
| rendering_info.colorAttachmentCount = attachment_count; |
| rendering_info.pColorAttachments = rendering_attachment_info.data(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRendering(rendering_info); |
| m_command_buffer.BindShaders(m_vert_shader, m_frag_shader); |
| SetDefaultDynamicStatesExclude({}, false, m_command_buffer); |
| |
| VkColorComponentFlags color_write_mask = |
| VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; |
| |
| for (uint32_t i = 0; i < attachment_count; ++i) { |
| VkBool32 color_blend_enable = i == 0; |
| vk::CmdSetColorBlendEnableEXT(m_command_buffer, i, 1u, &color_blend_enable); |
| vk::CmdSetColorWriteMaskEXT(m_command_buffer, i, 1u, &color_write_mask); |
| VkColorBlendAdvancedEXT color_blend_advanced; |
| color_blend_advanced.advancedBlendOp = VK_BLEND_OP_ADD; |
| color_blend_advanced.srcPremultiplied = VK_FALSE; |
| color_blend_advanced.dstPremultiplied = VK_FALSE; |
| color_blend_advanced.blendOverlap = VK_BLEND_OVERLAP_UNCORRELATED_EXT; |
| color_blend_advanced.clampResults = VK_FALSE; |
| vk::CmdSetColorBlendAdvancedEXT(m_command_buffer, i, 1u, &color_blend_advanced); |
| } |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-advancedBlendMaxColorAttachments-07480"); |
| vk::CmdDraw(m_command_buffer, 4u, 1u, 0u, 0u); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, CustomResolveSampleShadingImplicit) { |
| AddRequiredExtensions(VK_EXT_CUSTOM_RESOLVE_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::customResolve); |
| AddRequiredFeature(vkt::Feature::sampleRateShading); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| CreateMinimalShaders(); |
| |
| const char* fs_source = R"glsl( |
| #version 450 |
| layout(location = 0) out vec4 color; |
| void main() { |
| color = vec4(gl_SamplePosition.xyxy); |
| } |
| )glsl"; |
| |
| const auto fs_spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, fs_source); |
| VkShaderCreateInfoEXT fs_ci = ShaderCreateInfo(fs_spv, VK_SHADER_STAGE_FRAGMENT_BIT); |
| const vkt::Shader frag_shader(*m_device, fs_ci); |
| |
| vkt::Image color_image(*m_device, 128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::ImageView color_view = color_image.CreateView(); |
| VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper(); |
| color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| color_attachment.imageView = color_view; |
| |
| VkRenderingInfo begin_rendering_info = vku::InitStructHelper(); |
| begin_rendering_info.flags = VK_RENDERING_CUSTOM_RESOLVE_BIT_EXT | VK_RENDERING_FRAGMENT_REGION_BIT_EXT; |
| begin_rendering_info.colorAttachmentCount = 1; |
| begin_rendering_info.pColorAttachments = &color_attachment; |
| begin_rendering_info.layerCount = 1; |
| begin_rendering_info.renderArea = {{0, 0}, {1, 1}}; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRendering(begin_rendering_info); |
| SetDefaultDynamicStatesExclude({}, false, m_command_buffer); |
| VkBeginCustomResolveInfoEXT begin_resolve_info = vku::InitStructHelper(); |
| vk::CmdBeginCustomResolveEXT(m_command_buffer, &begin_resolve_info); |
| m_command_buffer.BindShaders(m_vert_shader, frag_shader); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-flags-11521"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidVertexBuffer) { |
| TEST_DESCRIPTION("Have Binding not be in a linear order"); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitRenderTarget(); |
| |
| const char* vs_source = R"glsl( |
| #version 450 |
| layout(location=0) in vec4 x; |
| layout(location=1) in vec4 y; |
| layout(location=2) in vec4 z; |
| void main(){} |
| )glsl"; |
| |
| vkt::Buffer vtx_buf(*m_device, 32, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); |
| |
| const auto vs_spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, vs_source); |
| auto vs_shader_ci = ShaderCreateInfoNoNextStage(vs_spv, VK_SHADER_STAGE_VERTEX_BIT); |
| vs_shader_ci.nextStage = VK_SHADER_STAGE_FRAGMENT_BIT; |
| const vkt::Shader vert_shader(*m_device, vs_shader_ci); |
| |
| const auto fs_spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| const vkt::Shader frag_shader(*m_device, ShaderCreateInfoNoNextStage(fs_spv, VK_SHADER_STAGE_FRAGMENT_BIT)); |
| |
| VkVertexInputBindingDescription2EXT vtx_binding_des[3]; |
| vtx_binding_des[0] = vku::InitStructHelper(); |
| vtx_binding_des[0].binding = 3u; |
| vtx_binding_des[0].stride = 0u; |
| vtx_binding_des[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX; |
| vtx_binding_des[0].divisor = 1u; |
| vtx_binding_des[1] = vku::InitStructHelper(); |
| vtx_binding_des[1].binding = 5u; |
| vtx_binding_des[1].stride = 0u; |
| vtx_binding_des[1].inputRate = VK_VERTEX_INPUT_RATE_VERTEX; |
| vtx_binding_des[1].divisor = 1u; |
| vtx_binding_des[2] = vku::InitStructHelper(); |
| vtx_binding_des[2].binding = 2u; |
| vtx_binding_des[2].stride = 0u; |
| vtx_binding_des[2].inputRate = VK_VERTEX_INPUT_RATE_VERTEX; |
| vtx_binding_des[2].divisor = 1u; |
| |
| VkVertexInputAttributeDescription2EXT vtx_attri_des[3]; |
| vtx_attri_des[0] = vku::InitStructHelper(); |
| vtx_attri_des[0].location = 0u; |
| vtx_attri_des[0].binding = 5u; |
| vtx_attri_des[0].format = VK_FORMAT_R8G8B8A8_UNORM; |
| vtx_attri_des[0].offset = 0u; |
| vtx_attri_des[1] = vku::InitStructHelper(); |
| vtx_attri_des[1].location = 1u; |
| vtx_attri_des[1].binding = 3u; |
| vtx_attri_des[1].format = VK_FORMAT_R8G8B8A8_UNORM; |
| vtx_attri_des[1].offset = 0u; |
| vtx_attri_des[2] = vku::InitStructHelper(); |
| vtx_attri_des[2].location = 2u; |
| vtx_attri_des[2].binding = 2u; |
| vtx_attri_des[2].format = VK_FORMAT_R8G8B8A8_UNORM; |
| vtx_attri_des[2].offset = 0u; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| VkDeviceSize offset = 0; |
| // Forget to update binding 2 |
| vk::CmdBindVertexBuffers(m_command_buffer, 5, 1, &vtx_buf.handle(), &offset); |
| vk::CmdBindVertexBuffers(m_command_buffer, 3, 1, &vtx_buf.handle(), &offset); |
| vk::CmdSetVertexInputEXT(m_command_buffer, 3u, vtx_binding_des, 3u, vtx_attri_des); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-04007"); |
| vk::CmdDraw(m_command_buffer, 1, 0, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, VertexStride) { |
| TEST_DESCRIPTION("Draw with vertex format components not matching vertex input format components."); |
| |
| AddRequiredFeature(vkt::Feature::shaderInt64); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const char vert_src[] = R"glsl( |
| #version 460 |
| layout(location = 0) in vec4 pos; |
| void main() { |
| gl_Position = vec4(pos.xy, pos.xy); |
| } |
| )glsl"; |
| |
| const vkt::Shader vert_shader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, vert_src); |
| const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| |
| VkVertexInputBindingDescription2EXT vertex_binding_description = vku::InitStructHelper(); |
| vertex_binding_description.binding = 0u; |
| vertex_binding_description.stride = 8u; |
| vertex_binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; |
| vertex_binding_description.divisor = 1u; |
| |
| VkVertexInputAttributeDescription2EXT vertex_attribute_description = vku::InitStructHelper(); |
| vertex_attribute_description.location = 0u; |
| vertex_attribute_description.binding = 0u; |
| vertex_attribute_description.format = VK_FORMAT_R32G32B32A32_SFLOAT; |
| vertex_attribute_description.offset = 0u; |
| |
| vk::CmdSetVertexInputEXT(m_command_buffer, 1u, &vertex_binding_description, 1u, &vertex_attribute_description); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindVertexBuffers2-pStrides-06209"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, VertexMisalignedAccess) { |
| AddRequiredFeature(vkt::Feature::shaderInt64); |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| const char vert_src[] = R"glsl( |
| #version 460 |
| layout(location = 0) in vec4 pos; |
| void main() { |
| gl_Position = pos; |
| } |
| )glsl"; |
| |
| const vkt::Shader vert_shader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, vert_src); |
| const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| m_vertex_buffer = new vkt::Buffer(*m_device, 256u, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| |
| VkVertexInputBindingDescription2EXT vertex_binding_description = vku::InitStructHelper(); |
| vertex_binding_description.binding = 0u; |
| vertex_binding_description.stride = 48u; |
| vertex_binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; |
| vertex_binding_description.divisor = 1u; |
| |
| VkVertexInputAttributeDescription2EXT vertex_attribute_description = vku::InitStructHelper(); |
| vertex_attribute_description.location = 0u; |
| vertex_attribute_description.binding = 0u; |
| vertex_attribute_description.format = VK_FORMAT_R32G32B32A32_SFLOAT; |
| vertex_attribute_description.offset = 6u; |
| |
| vk::CmdSetVertexInputEXT(m_command_buffer, 1u, &vertex_binding_description, 1u, &vertex_attribute_description); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-02721"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeShaderObject, InvalidImageLayout) { |
| TEST_DESCRIPTION("Test sampling from an image whose layout was never transitioned."); |
| |
| RETURN_IF_SKIP(InitBasicShaderObject()); |
| InitDynamicRenderTarget(); |
| |
| 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_}); |
| |
| const char frag_src[] = R"glsl( |
| #version 460 |
| layout(set = 0, binding = 0) uniform sampler2D s; |
| layout(location = 0) out vec4 uFragColor; |
| void main(){ |
| uFragColor = texture(s, vec2(0.5f)); |
| } |
| )glsl"; |
| |
| const auto vert_spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| const auto frag_spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, frag_src); |
| |
| VkDescriptorSetLayout descdriptor_set_layout = descriptor_set.layout_; |
| |
| const vkt::Shader vert_shader(*m_device, ShaderCreateInfo(vert_spv, VK_SHADER_STAGE_VERTEX_BIT, 1u, &descdriptor_set_layout)); |
| const vkt::Shader frag_shader(*m_device, ShaderCreateInfo(frag_spv, VK_SHADER_STAGE_FRAGMENT_BIT, 1u, &descdriptor_set_layout)); |
| |
| auto image_ci = vkt::Image::ImageCreateInfo2D(64, 64, 1, 2, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT); |
| vkt::Image image(*m_device, image_ci); |
| vkt::ImageView view = image.CreateView(VK_IMAGE_VIEW_TYPE_2D, 0, 1, 1, 1); |
| vkt::Sampler sampler(*m_device, SafeSaneSamplerCreateInfo()); |
| |
| descriptor_set.WriteDescriptorImageInfo(0, view, sampler, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, |
| VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); |
| descriptor_set.UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea()); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(vert_shader, frag_shader); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0u, 1u, &descriptor_set.set_, 0u, |
| nullptr); |
| vk::CmdDraw(m_command_buffer, 4, 1, 0, 0); |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| |
| // Draw expects VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL layout of sampled image |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-09600"); |
| m_default_queue->SubmitAndWait(m_command_buffer); |
| m_errorMonitor->VerifyFound(); |
| } |