| /* |
| * Copyright (c) 2015-2025 The Khronos Group Inc. |
| * Copyright (c) 2015-2025 Valve Corporation |
| * Copyright (c) 2015-2025 LunarG, Inc. |
| * Copyright (c) 2015-2025 Google, Inc. |
| * Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| */ |
| |
| #include "../framework/layer_validation_tests.h" |
| #include "../framework/pipeline_helper.h" |
| |
| class NegativePipelineBinary : public VkLayerTest {}; |
| |
| TEST_F(NegativePipelineBinary, GetPipelineKey) { |
| TEST_DESCRIPTION("Try getting the pipeline key with invalid input structures"); |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_PIPELINE_BINARY_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineBinaries); |
| RETURN_IF_SKIP(Init()); |
| |
| { |
| VkPipelineCreateInfoKHR pipeline_create_info = vku::InitStructHelper(); |
| VkDescriptorSetLayoutCreateInfo layout_create_info = vku::InitStructHelper(); |
| VkPipelineBinaryKeyKHR pipeline_key = vku::InitStructHelper(); |
| |
| pipeline_create_info.pNext = &layout_create_info; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineCreateInfoKHR-pNext-09604"); |
| vk::GetPipelineKeyKHR(device(), &pipeline_create_info, &pipeline_key); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| { |
| VkShaderObj cs(*m_device, kMinimalShaderGlsl, VK_SHADER_STAGE_COMPUTE_BIT); |
| |
| std::vector<VkDescriptorSetLayoutBinding> bindings(0); |
| const vkt::DescriptorSetLayout pipeline_dsl(*m_device, bindings); |
| const vkt::PipelineLayout pipeline_layout(*m_device, {&pipeline_dsl}); |
| |
| VkComputePipelineCreateInfo compute_create_info = vku::InitStructHelper(); |
| compute_create_info.stage = cs.GetStageCreateInfo(); |
| compute_create_info.layout = pipeline_layout; |
| |
| VkPipelineBinaryInfoKHR pipeline_binary_info = vku::InitStructHelper(); |
| pipeline_binary_info.binaryCount = 1; |
| |
| compute_create_info.pNext = &pipeline_binary_info; |
| |
| VkPipelineCreateInfoKHR pipeline_create_info = vku::InitStructHelper(&compute_create_info); |
| |
| VkPipelineBinaryKeyKHR pipeline_key = vku::InitStructHelper(); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetPipelineKeyKHR-pNext-09605"); |
| vk::GetPipelineKeyKHR(device(), &pipeline_create_info, &pipeline_key); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| TEST_F(NegativePipelineBinary, ReleaseCapturedDataAllocator) { |
| TEST_DESCRIPTION("Test using ReleaseCapturedData with/without an allocator"); |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_5_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance5); |
| AddRequiredExtensions(VK_KHR_PIPELINE_BINARY_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineBinaries); |
| RETURN_IF_SKIP(Init()); |
| |
| struct Alloc { |
| static VKAPI_ATTR void *VKAPI_CALL alloc(void *, size_t size, size_t, VkSystemAllocationScope) { return malloc(size); }; |
| static VKAPI_ATTR void *VKAPI_CALL reallocFunc(void *, void *original, size_t size, size_t, VkSystemAllocationScope) { |
| return realloc(original, size); |
| }; |
| static VKAPI_ATTR void VKAPI_CALL freeFunc(void *, void *ptr) { free(ptr); }; |
| static VKAPI_ATTR void VKAPI_CALL internalAlloc(void *, size_t, VkInternalAllocationType, VkSystemAllocationScope){}; |
| static VKAPI_ATTR void VKAPI_CALL internalFree(void *, size_t, VkInternalAllocationType, VkSystemAllocationScope){}; |
| }; |
| const VkAllocationCallbacks allocator = {nullptr, Alloc::alloc, Alloc::reallocFunc, Alloc::freeFunc, nullptr, nullptr}; |
| |
| VkShaderObj cs(*m_device, kMinimalShaderGlsl, VK_SHADER_STAGE_COMPUTE_BIT); |
| |
| std::vector<VkDescriptorSetLayoutBinding> bindings(0); |
| const vkt::DescriptorSetLayout pipeline_dsl(*m_device, bindings); |
| const vkt::PipelineLayout pipeline_layout(*m_device, {&pipeline_dsl}); |
| |
| VkComputePipelineCreateInfo compute_create_info = vku::InitStructHelper(); |
| compute_create_info.stage = cs.GetStageCreateInfo(); |
| compute_create_info.layout = pipeline_layout; |
| |
| VkPipelineCreateFlags2CreateInfo flags2 = vku::InitStructHelper(); |
| flags2.flags = VK_PIPELINE_CREATE_2_CAPTURE_DATA_BIT_KHR; |
| compute_create_info.pNext = &flags2; |
| |
| VkPipeline test_pipeline_with_allocator; |
| VkResult err = |
| vk::CreateComputePipelines(device(), VK_NULL_HANDLE, 1, &compute_create_info, &allocator, &test_pipeline_with_allocator); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| VkPipeline test_pipeline_no_allocator; |
| err = vk::CreateComputePipelines(device(), VK_NULL_HANDLE, 1, &compute_create_info, nullptr, &test_pipeline_no_allocator); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| VkReleaseCapturedPipelineDataInfoKHR data_info = vku::InitStructHelper(); |
| |
| data_info.pipeline = test_pipeline_with_allocator; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkReleaseCapturedPipelineDataKHR-pipeline-09611"); |
| vk::ReleaseCapturedPipelineDataKHR(device(), &data_info, nullptr); |
| m_errorMonitor->VerifyFound(); |
| |
| data_info.pipeline = test_pipeline_no_allocator; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkReleaseCapturedPipelineDataKHR-pipeline-09612"); |
| vk::ReleaseCapturedPipelineDataKHR(device(), &data_info, &allocator); |
| m_errorMonitor->VerifyFound(); |
| |
| vk::DestroyPipeline(device(), test_pipeline_with_allocator, &allocator); |
| vk::DestroyPipeline(device(), test_pipeline_no_allocator, nullptr); |
| } |
| |
| TEST_F(NegativePipelineBinary, ReleaseCapturedData) { |
| TEST_DESCRIPTION("Test using ReleaseCapturedPipelineDataKHR in a bad state"); |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_PIPELINE_BINARY_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineBinaries); |
| RETURN_IF_SKIP(Init()); |
| |
| CreateComputePipelineHelper pipe(*this); |
| pipe.CreateComputePipeline(); |
| |
| { |
| VkReleaseCapturedPipelineDataInfoKHR data_info = vku::InitStructHelper(); |
| data_info.pipeline = pipe; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkReleaseCapturedPipelineDataInfoKHR-pipeline-09613"); |
| vk::ReleaseCapturedPipelineDataKHR(device(), &data_info, nullptr); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| VkPipelineCreateFlags2CreateInfo flags2 = vku::InitStructHelper(); |
| flags2.flags = VK_PIPELINE_CREATE_2_CAPTURE_DATA_BIT_KHR; |
| |
| CreateComputePipelineHelper pipe2(*this, &flags2); |
| pipe2.CreateComputePipeline(true, true); |
| |
| { |
| VkReleaseCapturedPipelineDataInfoKHR data_info = vku::InitStructHelper(); |
| data_info.pipeline = pipe2; |
| |
| vk::ReleaseCapturedPipelineDataKHR(device(), &data_info, nullptr); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkReleaseCapturedPipelineDataInfoKHR-pipeline-09618"); |
| vk::ReleaseCapturedPipelineDataKHR(device(), &data_info, nullptr); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| TEST_F(NegativePipelineBinary, Destroy) { |
| TEST_DESCRIPTION("Test using DestroyPipelineBinary with/without an allocator"); |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_5_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance5); |
| AddRequiredExtensions(VK_KHR_PIPELINE_BINARY_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineBinaries); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPipelineCreateFlags2CreateInfo flags2 = vku::InitStructHelper(); |
| flags2.flags = VK_PIPELINE_CREATE_2_CAPTURE_DATA_BIT_KHR; |
| |
| CreateComputePipelineHelper pipe(*this, &flags2); |
| pipe.CreateComputePipeline(true, true); |
| |
| struct Alloc { |
| static VKAPI_ATTR void *VKAPI_CALL alloc(void *, size_t size, size_t, VkSystemAllocationScope) { return malloc(size); }; |
| static VKAPI_ATTR void *VKAPI_CALL reallocFunc(void *, void *original, size_t size, size_t, VkSystemAllocationScope) { |
| return realloc(original, size); |
| }; |
| static VKAPI_ATTR void VKAPI_CALL freeFunc(void *, void *ptr) { free(ptr); }; |
| static VKAPI_ATTR void VKAPI_CALL internalAlloc(void *, size_t, VkInternalAllocationType, VkSystemAllocationScope){}; |
| static VKAPI_ATTR void VKAPI_CALL internalFree(void *, size_t, VkInternalAllocationType, VkSystemAllocationScope){}; |
| }; |
| const VkAllocationCallbacks allocator = {nullptr, Alloc::alloc, Alloc::reallocFunc, Alloc::freeFunc, nullptr, nullptr}; |
| |
| VkPipelineBinaryCreateInfoKHR binary_create_info = vku::InitStructHelper(); |
| binary_create_info.pipeline = pipe; |
| |
| VkPipelineBinaryHandlesInfoKHR handles_info = vku::InitStructHelper(); |
| handles_info.pipelineBinaryCount = 1; |
| |
| VkPipelineBinaryKHR pipeline_binary_alloc; |
| handles_info.pPipelineBinaries = &pipeline_binary_alloc; |
| VkResult err = vk::CreatePipelineBinariesKHR(device(), &binary_create_info, &allocator, &handles_info); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkDestroyPipelineBinaryKHR-pipelineBinary-09614"); |
| vk::DestroyPipelineBinaryKHR(device(), pipeline_binary_alloc, nullptr); |
| m_errorMonitor->VerifyFound(); |
| vk::DestroyPipelineBinaryKHR(device(), pipeline_binary_alloc, &allocator); |
| |
| VkPipelineBinaryKHR pipeline_binary_no_alloc; |
| handles_info.pPipelineBinaries = &pipeline_binary_no_alloc; |
| err = vk::CreatePipelineBinariesKHR(device(), &binary_create_info, nullptr, &handles_info); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkDestroyPipelineBinaryKHR-pipelineBinary-09615"); |
| vk::DestroyPipelineBinaryKHR(device(), pipeline_binary_no_alloc, &allocator); |
| m_errorMonitor->VerifyFound(); |
| vk::DestroyPipelineBinaryKHR(device(), pipeline_binary_no_alloc, nullptr); |
| } |
| |
| TEST_F(NegativePipelineBinary, ComputePipeline) { |
| TEST_DESCRIPTION("Test creating a compute pipeline with bad pipeline binary settings"); |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_5_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance5); |
| AddRequiredExtensions(VK_KHR_PIPELINE_BINARY_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineBinaries); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPipelineCache pipeline_cache; |
| VkPipelineCacheCreateInfo cache_create_info = vku::InitStructHelper(); |
| cache_create_info.initialDataSize = 0; |
| VkResult err = vk::CreatePipelineCache(device(), &cache_create_info, nullptr, &pipeline_cache); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| { |
| VkPipelineCreateFlags2CreateInfo flags2 = vku::InitStructHelper(); |
| flags2.flags = VK_PIPELINE_CREATE_2_CAPTURE_DATA_BIT_KHR; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateComputePipelines-pNext-09617"); |
| CreateComputePipelineHelper pipe(*this, &flags2); |
| pipe.CreateComputePipeline(true, false); |
| m_errorMonitor->VerifyFound(); |
| |
| pipe.CreateComputePipeline(true, true); |
| |
| VkPipelineBinaryCreateInfoKHR binary_create_info = vku::InitStructHelper(); |
| binary_create_info.pipeline = pipe; |
| |
| VkPipelineBinaryHandlesInfoKHR handles_info = vku::InitStructHelper(); |
| handles_info.pipelineBinaryCount = 1; |
| |
| err = vk::CreatePipelineBinariesKHR(device(), &binary_create_info, nullptr, &handles_info); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| std::vector<VkPipelineBinaryKHR> binaries(handles_info.pipelineBinaryCount); |
| handles_info.pPipelineBinaries = binaries.data(); |
| |
| err = vk::CreatePipelineBinariesKHR(device(), &binary_create_info, nullptr, &handles_info); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| VkPipelineBinaryInfoKHR binary_info = vku::InitStructHelper(); |
| binary_info.binaryCount = handles_info.pipelineBinaryCount; |
| binary_info.pPipelineBinaries = handles_info.pPipelineBinaries; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateComputePipelines-pNext-09616"); |
| CreateComputePipelineHelper pipe2(*this, &binary_info); |
| pipe2.CreateComputePipeline(true, false); |
| m_errorMonitor->VerifyFound(); |
| |
| for (uint32_t i = 0; i < binaries.size(); i++) { |
| vk::DestroyPipelineBinaryKHR(device(), binaries[i], nullptr); |
| } |
| } |
| |
| { |
| VkPipelineCreateFlags2CreateInfo flags2 = vku::InitStructHelper(); |
| flags2.flags = VK_PIPELINE_CREATE_2_CAPTURE_DATA_BIT_KHR; |
| |
| CreateComputePipelineHelper pipe(*this, &flags2); |
| pipe.CreateComputePipeline(true, true); |
| |
| VkPipelineBinaryCreateInfoKHR binary_create_info = vku::InitStructHelper(); |
| binary_create_info.pipeline = pipe; |
| |
| VkPipelineBinaryHandlesInfoKHR handles_info = vku::InitStructHelper(); |
| handles_info.pipelineBinaryCount = 1; |
| |
| err = vk::CreatePipelineBinariesKHR(device(), &binary_create_info, nullptr, &handles_info); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| std::vector<VkPipelineBinaryKHR> binaries(handles_info.pipelineBinaryCount); |
| handles_info.pPipelineBinaries = binaries.data(); |
| |
| err = vk::CreatePipelineBinariesKHR(device(), &binary_create_info, nullptr, &handles_info); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| VkPipelineBinaryInfoKHR binary_info = vku::InitStructHelper(); |
| binary_info.binaryCount = handles_info.pipelineBinaryCount; |
| binary_info.pPipelineBinaries = handles_info.pPipelineBinaries; |
| |
| VkPipelineCreationFeedbackCreateInfo feedback_create_info = vku::InitStructHelper(); |
| VkPipelineCreationFeedback feedback = {}; |
| |
| feedback_create_info.pPipelineCreationFeedback = &feedback; |
| feedback.flags = VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT | |
| VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT; |
| |
| flags2.flags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT; |
| flags2.pNext = &binary_info; |
| binary_info.pNext = &feedback_create_info; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateComputePipelines-binaryCount-09620"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateComputePipelines-binaryCount-09621"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateComputePipelines-binaryCount-09622"); |
| CreateComputePipelineHelper pipe2(*this, &flags2); |
| pipe2.CreateComputePipeline(true, true); |
| m_errorMonitor->VerifyFound(); |
| |
| for (uint32_t i = 0; i < binaries.size(); i++) { |
| vk::DestroyPipelineBinaryKHR(device(), binaries[i], nullptr); |
| } |
| } |
| |
| vk::DestroyPipelineCache(device(), pipeline_cache, nullptr); |
| } |
| |
| TEST_F(NegativePipelineBinary, GraphicsPipeline) { |
| TEST_DESCRIPTION("Test creating a graphics pipeline with bad pipeline binary settings"); |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_5_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance5); |
| AddRequiredExtensions(VK_KHR_PIPELINE_BINARY_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineBinaries); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPipelineCache pipeline_cache; |
| VkPipelineCacheCreateInfo cache_create_info = vku::InitStructHelper(); |
| cache_create_info.initialDataSize = 0; |
| VkResult err = vk::CreatePipelineCache(device(), &cache_create_info, nullptr, &pipeline_cache); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| m_depth_stencil_fmt = FindSupportedDepthStencilFormat(Gpu()); |
| |
| m_depthStencil->Init(*m_device, m_width, m_height, 1, m_depth_stencil_fmt, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); |
| vkt::ImageView depth_image_view = m_depthStencil->CreateView(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); |
| InitRenderTarget(&depth_image_view.handle()); |
| |
| VkShaderObj vs(*m_device, kVertexMinimalGlsl, VK_SHADER_STAGE_VERTEX_BIT); |
| |
| const VkPipelineVertexInputStateCreateInfo pipeline_vertex_input_state_create_info{ |
| VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, nullptr, 0, 0, nullptr, 0, nullptr}; |
| |
| const VkPipelineInputAssemblyStateCreateInfo pipeline_input_assembly_state_create_info{ |
| VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_FALSE}; |
| |
| const VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_create_info_template{ |
| VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, |
| nullptr, |
| 0, |
| VK_FALSE, |
| VK_FALSE, |
| VK_POLYGON_MODE_FILL, |
| VK_CULL_MODE_NONE, |
| VK_FRONT_FACE_COUNTER_CLOCKWISE, |
| VK_FALSE, |
| 0.0f, |
| 0.0f, |
| 0.0f, |
| 1.0f}; |
| |
| VkPipelineLayout pipeline_layout; |
| VkPipelineLayoutCreateInfo pipeline_layout_create_info = vku::InitStructHelper(); |
| err = vk::CreatePipelineLayout(device(), &pipeline_layout_create_info, nullptr, &pipeline_layout); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_create_info = |
| pipeline_rasterization_state_create_info_template; |
| pipeline_rasterization_state_create_info.rasterizerDiscardEnable = VK_TRUE; |
| |
| VkGraphicsPipelineCreateInfo graphics_pipeline_create_info{VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, |
| nullptr, |
| 0, |
| 1, |
| &vs.GetStageCreateInfo(), |
| &pipeline_vertex_input_state_create_info, |
| &pipeline_input_assembly_state_create_info, |
| nullptr, |
| nullptr, |
| &pipeline_rasterization_state_create_info, |
| nullptr, |
| nullptr, |
| nullptr, |
| nullptr, |
| pipeline_layout, |
| m_renderPass, |
| 0, |
| 0, |
| 0}; |
| |
| { |
| VkPipelineCreateFlags2CreateInfo flags2 = vku::InitStructHelper(); |
| flags2.flags = VK_PIPELINE_CREATE_2_CAPTURE_DATA_BIT_KHR; |
| graphics_pipeline_create_info.pNext = &flags2; |
| |
| VkPipeline test_pipeline; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateGraphicsPipelines-pNext-09617"); |
| vk::CreateGraphicsPipelines(device(), pipeline_cache, 1, &graphics_pipeline_create_info, nullptr, &test_pipeline); |
| m_errorMonitor->VerifyFound(); |
| |
| err = vk::CreateGraphicsPipelines(device(), VK_NULL_HANDLE, 1, &graphics_pipeline_create_info, nullptr, &test_pipeline); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| VkPipelineBinaryCreateInfoKHR binary_create_info = vku::InitStructHelper(); |
| binary_create_info.pipeline = test_pipeline; |
| |
| VkPipelineBinaryHandlesInfoKHR handles_info = vku::InitStructHelper(); |
| handles_info.pipelineBinaryCount = 1; |
| |
| err = vk::CreatePipelineBinariesKHR(device(), &binary_create_info, nullptr, &handles_info); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| std::vector<VkPipelineBinaryKHR> binaries(handles_info.pipelineBinaryCount); |
| handles_info.pPipelineBinaries = binaries.data(); |
| |
| err = vk::CreatePipelineBinariesKHR(device(), &binary_create_info, nullptr, &handles_info); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| VkPipelineBinaryInfoKHR binary_info = vku::InitStructHelper(); |
| binary_info.binaryCount = handles_info.pipelineBinaryCount; |
| binary_info.pPipelineBinaries = handles_info.pPipelineBinaries; |
| |
| graphics_pipeline_create_info.pNext = &binary_info; |
| |
| VkPipeline test_pipeline2; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateGraphicsPipelines-pNext-09616"); |
| vk::CreateGraphicsPipelines(device(), pipeline_cache, 1, &graphics_pipeline_create_info, nullptr, &test_pipeline2); |
| m_errorMonitor->VerifyFound(); |
| |
| for (uint32_t i = 0; i < binaries.size(); i++) { |
| vk::DestroyPipelineBinaryKHR(device(), binaries[i], nullptr); |
| } |
| |
| vk::DestroyPipeline(device(), test_pipeline, nullptr); |
| } |
| |
| { |
| VkPipelineCreateFlags2CreateInfo flags2 = vku::InitStructHelper(); |
| flags2.flags = VK_PIPELINE_CREATE_2_CAPTURE_DATA_BIT_KHR; |
| graphics_pipeline_create_info.pNext = &flags2; |
| |
| VkPipeline test_pipeline; |
| |
| err = vk::CreateGraphicsPipelines(device(), VK_NULL_HANDLE, 1, &graphics_pipeline_create_info, nullptr, &test_pipeline); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| VkPipelineBinaryCreateInfoKHR binary_create_info = vku::InitStructHelper(); |
| binary_create_info.pipeline = test_pipeline; |
| |
| VkPipelineBinaryHandlesInfoKHR handles_info = vku::InitStructHelper(); |
| handles_info.pipelineBinaryCount = 1; |
| |
| err = vk::CreatePipelineBinariesKHR(device(), &binary_create_info, nullptr, &handles_info); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| std::vector<VkPipelineBinaryKHR> binaries(handles_info.pipelineBinaryCount); |
| handles_info.pPipelineBinaries = binaries.data(); |
| |
| err = vk::CreatePipelineBinariesKHR(device(), &binary_create_info, nullptr, &handles_info); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| VkPipelineBinaryInfoKHR binary_info = vku::InitStructHelper(); |
| binary_info.binaryCount = handles_info.pipelineBinaryCount; |
| binary_info.pPipelineBinaries = handles_info.pPipelineBinaries; |
| |
| VkPipelineCreationFeedbackCreateInfo feedback_create_info = vku::InitStructHelper(); |
| VkPipelineCreationFeedback feedback = {}; |
| |
| feedback_create_info.pPipelineCreationFeedback = &feedback; |
| feedback.flags = VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT | |
| VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT; |
| |
| flags2.flags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT; |
| flags2.pNext = &binary_info; |
| binary_info.pNext = &feedback_create_info; |
| |
| VkPipeline test_pipeline2; |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateGraphicsPipelines-binaryCount-09620"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateGraphicsPipelines-binaryCount-09621"); |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateGraphicsPipelines-binaryCount-09622"); |
| |
| vk::CreateGraphicsPipelines(device(), VK_NULL_HANDLE, 1, &graphics_pipeline_create_info, nullptr, &test_pipeline2); |
| m_errorMonitor->VerifyFound(); |
| |
| for (uint32_t i = 0; i < binaries.size(); i++) { |
| vk::DestroyPipelineBinaryKHR(device(), binaries[i], nullptr); |
| } |
| |
| vk::DestroyPipeline(device(), test_pipeline, nullptr); |
| } |
| |
| vk::DestroyPipelineLayout(device(), pipeline_layout, nullptr); |
| vk::DestroyPipelineCache(device(), pipeline_cache, nullptr); |
| } |
| |
| TEST_F(NegativePipelineBinary, Creation1) { |
| TEST_DESCRIPTION("Test creating pipeline binaries with invalid parameters"); |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_5_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance5); |
| AddRequiredExtensions(VK_KHR_PIPELINE_BINARY_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineBinaries); |
| RETURN_IF_SKIP(Init()); |
| |
| CreateComputePipelineHelper pipe(*this); |
| pipe.CreateComputePipeline(true, true); |
| |
| VkPipelineBinaryCreateInfoKHR binary_create_info = vku::InitStructHelper(); |
| binary_create_info.pipeline = pipe; |
| |
| VkPipelineBinaryKHR pipeline_binary; |
| VkPipelineBinaryHandlesInfoKHR handles_info = vku::InitStructHelper(); |
| handles_info.pipelineBinaryCount = 1; |
| handles_info.pPipelineBinaries = &pipeline_binary; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineBinaryCreateInfoKHR-pipeline-09607"); |
| vk::CreatePipelineBinariesKHR(device(), &binary_create_info, nullptr, &handles_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativePipelineBinary, Creation2) { |
| TEST_DESCRIPTION("Test creating pipeline binaries with invalid parameters"); |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_5_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance5); |
| AddRequiredExtensions(VK_KHR_PIPELINE_BINARY_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineBinaries); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPipelineCreateFlags2CreateInfo flags2 = vku::InitStructHelper(); |
| flags2.flags = VK_PIPELINE_CREATE_2_CAPTURE_DATA_BIT_KHR; |
| |
| CreateComputePipelineHelper pipe(*this, &flags2); |
| pipe.CreateComputePipeline(true, true); |
| |
| VkReleaseCapturedPipelineDataInfoKHR release_info = vku::InitStructHelper(); |
| release_info.pipeline = pipe; |
| |
| VkResult err = vk::ReleaseCapturedPipelineDataKHR(device(), &release_info, nullptr); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| VkPipelineBinaryCreateInfoKHR binary_create_info = vku::InitStructHelper(); |
| binary_create_info.pipeline = pipe; |
| |
| VkPipelineBinaryKHR pipeline_binary; |
| VkPipelineBinaryHandlesInfoKHR handles_info = vku::InitStructHelper(); |
| handles_info.pipelineBinaryCount = 1; |
| handles_info.pPipelineBinaries = &pipeline_binary; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineBinaryCreateInfoKHR-pipeline-09608"); |
| vk::CreatePipelineBinariesKHR(device(), &binary_create_info, nullptr, &handles_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativePipelineBinary, Creation3) { |
| TEST_DESCRIPTION("Test creating pipeline binaries with invalid parameters"); |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_5_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance5); |
| AddRequiredExtensions(VK_KHR_PIPELINE_BINARY_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineBinaries); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDevicePipelineBinaryPropertiesKHR pipeline_binary_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(pipeline_binary_properties); |
| |
| if (pipeline_binary_properties.pipelineBinaryInternalCache) { |
| GTEST_SKIP() << "pipelineBinaryInternalCache is VK_TRUE"; |
| } |
| |
| VkShaderObj cs(*m_device, kMinimalShaderGlsl, VK_SHADER_STAGE_COMPUTE_BIT); |
| |
| std::vector<VkDescriptorSetLayoutBinding> bindings(0); |
| const vkt::DescriptorSetLayout pipeline_dsl(*m_device, bindings); |
| const vkt::PipelineLayout pipeline_layout(*m_device, {&pipeline_dsl}); |
| |
| VkComputePipelineCreateInfo compute_create_info = vku::InitStructHelper(); |
| compute_create_info.stage = cs.GetStageCreateInfo(); |
| compute_create_info.layout = pipeline_layout; |
| |
| VkPipelineCreateFlags2CreateInfo flags2 = vku::InitStructHelper(); |
| flags2.flags = VK_PIPELINE_CREATE_2_CAPTURE_DATA_BIT_KHR; |
| compute_create_info.pNext = &flags2; |
| |
| VkPipelineCreateInfoKHR pipeline_create_info = vku::InitStructHelper(&compute_create_info); |
| |
| VkPipelineBinaryCreateInfoKHR binary_create_info = vku::InitStructHelper(); |
| binary_create_info.pPipelineCreateInfo = &pipeline_create_info; |
| |
| VkPipelineBinaryKHR pipeline_binary; |
| VkPipelineBinaryHandlesInfoKHR handles_info = vku::InitStructHelper(); |
| handles_info.pipelineBinaryCount = 1; |
| handles_info.pPipelineBinaries = &pipeline_binary; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineBinaryCreateInfoKHR-pipelineBinaryInternalCache-09609"); |
| vk::CreatePipelineBinariesKHR(device(), &binary_create_info, nullptr, &handles_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativePipelineBinary, Creation4) { |
| TEST_DESCRIPTION("Test creating pipeline binaries with invalid parameters"); |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_5_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance5); |
| AddRequiredExtensions(VK_KHR_PIPELINE_BINARY_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineBinaries); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPipelineCreateFlags2CreateInfo flags2 = vku::InitStructHelper(); |
| flags2.flags = VK_PIPELINE_CREATE_2_CAPTURE_DATA_BIT_KHR; |
| |
| CreateComputePipelineHelper pipe(*this, &flags2); |
| pipe.CreateComputePipeline(true, true); |
| |
| VkPipelineCreateInfoKHR pipeline_create_info = vku::InitStructHelper(&pipe.cp_ci_); |
| |
| VkPipelineBinaryCreateInfoKHR binary_create_info = vku::InitStructHelper(); |
| |
| VkPipelineBinaryKHR pipeline_binary; |
| VkPipelineBinaryHandlesInfoKHR handles_info = vku::InitStructHelper(); |
| handles_info.pipelineBinaryCount = 1; |
| handles_info.pPipelineBinaries = &pipeline_binary; |
| |
| // test 0 |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineBinaryCreateInfoKHR-pKeysAndDataInfo-09619"); |
| vk::CreatePipelineBinariesKHR(device(), &binary_create_info, nullptr, &handles_info); |
| m_errorMonitor->VerifyFound(); |
| |
| // test > 0 |
| binary_create_info.pipeline = pipe; |
| binary_create_info.pPipelineCreateInfo = &pipeline_create_info; |
| |
| VkPhysicalDevicePipelineBinaryPropertiesKHR pipeline_binary_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(pipeline_binary_properties); |
| if (!pipeline_binary_properties.pipelineBinaryInternalCache) { |
| m_errorMonitor->SetUnexpectedError("VUID-VkPipelineBinaryCreateInfoKHR-pipelineBinaryInternalCache-09609"); |
| } |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineBinaryCreateInfoKHR-pKeysAndDataInfo-09619"); |
| vk::CreatePipelineBinariesKHR(device(), &binary_create_info, nullptr, &handles_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativePipelineBinary, Creation5) { |
| TEST_DESCRIPTION("Test creating pipeline binaries with invalid parameters"); |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_5_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance5); |
| AddRequiredExtensions(VK_KHR_PIPELINE_BINARY_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineBinaries); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDevicePipelineBinaryPropertiesKHR pipeline_binary_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(pipeline_binary_properties); |
| if (!pipeline_binary_properties.pipelineBinaryInternalCache) { |
| GTEST_SKIP() << "pipelineBinaryInternalCache is VK_FALSE"; |
| } |
| |
| VkPipelineCreateFlags2CreateInfo flags2 = vku::InitStructHelper(); |
| flags2.flags = VK_PIPELINE_CREATE_2_CAPTURE_DATA_BIT_KHR; |
| |
| CreateComputePipelineHelper pipe(*this, &flags2); |
| pipe.CreateComputePipeline(true, true); |
| |
| VkPipelineBinaryCreateInfoKHR binary_create_info = vku::InitStructHelper(); |
| binary_create_info.pipeline = pipe; |
| |
| VkPipelineBinaryHandlesInfoKHR handles_info = vku::InitStructHelper(); |
| |
| VkResult err = vk::CreatePipelineBinariesKHR(device(), &binary_create_info, nullptr, &handles_info); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| std::vector<VkPipelineBinaryKHR> binaries(handles_info.pipelineBinaryCount); |
| handles_info.pPipelineBinaries = binaries.data(); |
| |
| err = vk::CreatePipelineBinariesKHR(device(), &binary_create_info, nullptr, &handles_info); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| VkPipelineCreateInfoKHR pipeline_create_info = vku::InitStructHelper(&pipe.cp_ci_); |
| |
| VkPipelineBinaryInfoKHR binary_info = vku::InitStructHelper(); |
| binary_info.binaryCount = binaries.size(); |
| binary_info.pPipelineBinaries = binaries.data(); |
| flags2.pNext = &binary_info; |
| |
| handles_info.pPipelineBinaries = nullptr; |
| binary_create_info.pipeline = VK_NULL_HANDLE; |
| binary_create_info.pPipelineCreateInfo = &pipeline_create_info; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineBinaryCreateInfoKHR-pPipelineCreateInfo-09606"); |
| err = vk::CreatePipelineBinariesKHR(device(), &binary_create_info, nullptr, &handles_info); |
| m_errorMonitor->VerifyFound(); |
| |
| for (uint32_t i = 0; i < binaries.size(); i++) { |
| vk::DestroyPipelineBinaryKHR(device(), binaries[i], nullptr); |
| } |
| } |
| |
| TEST_F(NegativePipelineBinary, CreateCacheControl) { |
| TEST_DESCRIPTION("Creating pipeline binaries with internal cache disabled"); |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_5_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance5); |
| AddRequiredExtensions(VK_KHR_PIPELINE_BINARY_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineBinaries); |
| RETURN_IF_SKIP(InitFramework()); |
| |
| VkPhysicalDevicePipelineBinaryPropertiesKHR pipeline_binary_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(pipeline_binary_properties); |
| |
| if (!pipeline_binary_properties.pipelineBinaryInternalCacheControl) { |
| GTEST_SKIP() << "pipelineBinaryInternalCacheControl is VK_FALSE"; |
| } |
| |
| VkDevicePipelineBinaryInternalCacheControlKHR cache_control = vku::InitStructHelper(); |
| cache_control.disableInternalCache = VK_TRUE; |
| RETURN_IF_SKIP(InitState(nullptr, &cache_control)); |
| |
| VkShaderObj cs(*m_device, kMinimalShaderGlsl, VK_SHADER_STAGE_COMPUTE_BIT); |
| |
| std::vector<VkDescriptorSetLayoutBinding> bindings(0); |
| const vkt::DescriptorSetLayout pipeline_dsl(*m_device, bindings); |
| const vkt::PipelineLayout pipeline_layout(*m_device, {&pipeline_dsl}); |
| |
| VkComputePipelineCreateInfo compute_create_info = vku::InitStructHelper(); |
| compute_create_info.stage = cs.GetStageCreateInfo(); |
| compute_create_info.layout = pipeline_layout; |
| |
| VkPipelineCreateFlags2CreateInfo flags2 = vku::InitStructHelper(); |
| flags2.flags = VK_PIPELINE_CREATE_2_CAPTURE_DATA_BIT_KHR; |
| compute_create_info.pNext = &flags2; |
| |
| VkPipelineCreateInfoKHR pipeline_create_info = vku::InitStructHelper(&compute_create_info); |
| |
| VkPipelineBinaryCreateInfoKHR binary_create_info = vku::InitStructHelper(); |
| binary_create_info.pPipelineCreateInfo = &pipeline_create_info; |
| |
| VkPipelineBinaryKHR pipeline_binary; |
| VkPipelineBinaryHandlesInfoKHR handles_info = vku::InitStructHelper(); |
| handles_info.pipelineBinaryCount = 1; |
| handles_info.pPipelineBinaries = &pipeline_binary; |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineBinaryCreateInfoKHR-device-09610"); |
| vk::CreatePipelineBinariesKHR(device(), &binary_create_info, nullptr, &handles_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativePipelineBinary, InvalidPNext) { |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_PIPELINE_BINARY_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineBinaries); |
| RETURN_IF_SKIP(Init()); |
| |
| VkShaderObj cs(*m_device, kMinimalShaderGlsl, VK_SHADER_STAGE_COMPUTE_BIT); |
| |
| std::vector<VkDescriptorSetLayoutBinding> bindings(0); |
| const vkt::DescriptorSetLayout pipeline_dsl(*m_device, bindings); |
| const vkt::PipelineLayout pipeline_layout(*m_device, {&pipeline_dsl}); |
| |
| VkComputePipelineCreateInfo compute_create_info = vku::InitStructHelper(); |
| compute_create_info.stage = cs.GetStageCreateInfo(); |
| compute_create_info.layout = pipeline_layout; |
| |
| VkPipelineBinaryInfoKHR pipeline_binary_info = vku::InitStructHelper(); |
| pipeline_binary_info.binaryCount = 0; |
| |
| compute_create_info.pNext = &pipeline_binary_info; |
| |
| VkPipelineCreateInfoKHR pipeline_create_info = vku::InitStructHelper(&compute_create_info); |
| |
| VkPipelineBinaryKeyKHR pipeline_key = vku::InitStructHelper(&pipeline_create_info); |
| |
| m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineBinaryKeyKHR-pNext-pNext"); |
| vk::GetPipelineKeyKHR(device(), &pipeline_create_info, &pipeline_key); |
| m_errorMonitor->VerifyFound(); |
| } |