| 19 | class NegativeGpuAVIndirectBuffer : public GpuAVTest {}; |
| 20 | |
| 21 | TEST_F(NegativeGpuAVIndirectBuffer, DrawCountDeviceLimit) { |
| 22 | TEST_DESCRIPTION("GPU validation: Validate maxDrawIndirectCount limit"); |
| 23 | SetTargetApiVersion(VK_API_VERSION_1_3); |
| 24 | AddRequiredExtensions(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME); // instead of enabling feature |
| 25 | AddOptionalExtensions(VK_EXT_MESH_SHADER_EXTENSION_NAME); |
| 26 | RETURN_IF_SKIP(InitGpuAvFramework()); |
| 27 | |
| 28 | VkPhysicalDeviceMeshShaderFeaturesEXT mesh_shader_features = vku::InitStructHelper(); |
| 29 | VkPhysicalDeviceVulkan13Features features13 = vku::InitStructHelper(&mesh_shader_features); |
| 30 | bool mesh_shader_enabled = false; |
| 31 | if (DeviceValidationVersion() >= VK_API_VERSION_1_3) { |
| 32 | GetPhysicalDeviceFeatures2(mesh_shader_features); |
| 33 | mesh_shader_enabled = IsExtensionsEnabled(VK_EXT_MESH_SHADER_EXTENSION_NAME) && features13.maintenance4; |
| 34 | if (mesh_shader_enabled) { |
| 35 | mesh_shader_features.multiviewMeshShader = VK_FALSE; |
| 36 | mesh_shader_features.primitiveFragmentShadingRateMeshShader = VK_FALSE; |
| 37 | } |
| 38 | } |
| 39 | |
| 40 | PFN_vkSetPhysicalDeviceLimitsEXT fpvkSetPhysicalDeviceLimitsEXT = nullptr; |
| 41 | PFN_vkGetOriginalPhysicalDeviceLimitsEXT fpvkGetOriginalPhysicalDeviceLimitsEXT = nullptr; |
| 42 | if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceLimitsEXT, fpvkGetOriginalPhysicalDeviceLimitsEXT)) { |
| 43 | GTEST_SKIP() << "Failed to device profile layer."; |
| 44 | } |
| 45 | |
| 46 | VkPhysicalDeviceProperties props; |
| 47 | fpvkGetOriginalPhysicalDeviceLimitsEXT(Gpu(), &props.limits); |
| 48 | props.limits.maxDrawIndirectCount = 1; |
| 49 | fpvkSetPhysicalDeviceLimitsEXT(Gpu(), &props.limits); |
| 50 | |
| 51 | RETURN_IF_SKIP(InitState(nullptr, (features13.dynamicRendering || mesh_shader_enabled) ? (void*)&features13 : nullptr)); |
| 52 | InitRenderTarget(); |
| 53 | |
| 54 | vkt::Buffer draw_buffer(*m_device, 2 * sizeof(VkDrawIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, |
| 55 | kHostVisibleMemProps); |
| 56 | VkDrawIndirectCommand* draw_ptr = static_cast<VkDrawIndirectCommand*>(draw_buffer.Memory().Map()); |
| 57 | memset(draw_ptr, 0, 2 * sizeof(VkDrawIndirectCommand)); |
| 58 | |
| 59 | vkt::Buffer count_buffer(*m_device, sizeof(uint32_t), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, kHostVisibleMemProps); |
| 60 | uint32_t* count_ptr = static_cast<uint32_t*>(count_buffer.Memory().Map()); |
| 61 | *count_ptr = 2; // Fits in buffer but exceeds (fake) limit |
| 62 | |
| 63 | CreatePipelineHelper pipe(*this); |
| 64 | pipe.CreateGraphicsPipeline(); |
| 65 | |
| 66 | VkCommandBufferBeginInfo begin_info = vku::InitStructHelper(); |
| 67 | m_command_buffer.Begin(&begin_info); |
| 68 | m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| 69 | vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| 70 | |
| 71 | m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirectCount-countBuffer-02717"); |
| 72 | vk::CmdDrawIndirectCountKHR(m_command_buffer, draw_buffer, 0, count_buffer, 0, 2, sizeof(VkDrawIndirectCommand)); |
| 73 | |
| 74 | m_command_buffer.EndRenderPass(); |
| 75 | m_command_buffer.End(); |
| 76 | m_default_queue->SubmitAndWait(m_command_buffer); |
| 77 | m_errorMonitor->VerifyFound(); |
| 78 |
nothing calls this directly
no test coverage detected