15db71995Sopenharmony_ci/* 25db71995Sopenharmony_ci * Copyright (c) 2021 The Khronos Group Inc. 35db71995Sopenharmony_ci * Copyright (c) 2021 Valve Corporation 45db71995Sopenharmony_ci * Copyright (c) 2021 LunarG, Inc. 55db71995Sopenharmony_ci * 65db71995Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 75db71995Sopenharmony_ci * of this software and/or associated documentation files (the "Materials"), to 85db71995Sopenharmony_ci * deal in the Materials without restriction, including without limitation the 95db71995Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 105db71995Sopenharmony_ci * sell copies of the Materials, and to permit persons to whom the Materials are 115db71995Sopenharmony_ci * furnished to do so, subject to the following conditions: 125db71995Sopenharmony_ci * 135db71995Sopenharmony_ci * The above copyright notice(s) and this permission notice shall be included in 145db71995Sopenharmony_ci * all copies or substantial portions of the Materials. 155db71995Sopenharmony_ci * 165db71995Sopenharmony_ci * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 175db71995Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 185db71995Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 195db71995Sopenharmony_ci * 205db71995Sopenharmony_ci * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 215db71995Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 225db71995Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE 235db71995Sopenharmony_ci * USE OR OTHER DEALINGS IN THE MATERIALS. 245db71995Sopenharmony_ci * 255db71995Sopenharmony_ci * Author: Charles Giessen <charles@lunarg.com> 265db71995Sopenharmony_ci */ 275db71995Sopenharmony_ci 285db71995Sopenharmony_ci#include "test_environment.h" 295db71995Sopenharmony_ci 305db71995Sopenharmony_ci#include <mutex> 315db71995Sopenharmony_ci#include <thread> 325db71995Sopenharmony_ci#include <atomic> 335db71995Sopenharmony_ci 345db71995Sopenharmony_civoid create_destroy_instance_loop_with_function_queries(FrameworkEnvironment* env, uint32_t num_loops_create_destroy_instance, 355db71995Sopenharmony_ci uint32_t num_loops_try_get_instance_proc_addr, 365db71995Sopenharmony_ci uint32_t num_loops_try_get_device_proc_addr) { 375db71995Sopenharmony_ci for (uint32_t i = 0; i < num_loops_create_destroy_instance; i++) { 385db71995Sopenharmony_ci InstWrapper inst{env->vulkan_functions}; 395db71995Sopenharmony_ci inst.CheckCreate(); 405db71995Sopenharmony_ci PFN_vkEnumeratePhysicalDevices enum_pd = nullptr; 415db71995Sopenharmony_ci for (uint32_t j = 0; j < num_loops_try_get_instance_proc_addr; j++) { 425db71995Sopenharmony_ci enum_pd = inst.load("vkEnumeratePhysicalDevices"); 435db71995Sopenharmony_ci ASSERT_NE(enum_pd, nullptr); 445db71995Sopenharmony_ci } 455db71995Sopenharmony_ci VkPhysicalDevice phys_dev = inst.GetPhysDev(); 465db71995Sopenharmony_ci 475db71995Sopenharmony_ci DeviceWrapper dev{inst}; 485db71995Sopenharmony_ci dev.CheckCreate(phys_dev); 495db71995Sopenharmony_ci for (uint32_t j = 0; j < num_loops_try_get_device_proc_addr; j++) { 505db71995Sopenharmony_ci PFN_vkCmdBindPipeline p = dev.load("vkCmdBindPipeline"); 515db71995Sopenharmony_ci p(VK_NULL_HANDLE, VkPipelineBindPoint::VK_PIPELINE_BIND_POINT_GRAPHICS, VK_NULL_HANDLE); 525db71995Sopenharmony_ci } 535db71995Sopenharmony_ci } 545db71995Sopenharmony_ci} 555db71995Sopenharmony_ci 565db71995Sopenharmony_civoid create_destroy_device_loop(FrameworkEnvironment* env, uint32_t num_loops_create_destroy_device, 575db71995Sopenharmony_ci uint32_t num_loops_try_get_proc_addr) { 585db71995Sopenharmony_ci InstWrapper inst{env->vulkan_functions}; 595db71995Sopenharmony_ci inst.CheckCreate(); 605db71995Sopenharmony_ci for (uint32_t i = 0; i < num_loops_create_destroy_device; i++) { 615db71995Sopenharmony_ci DeviceWrapper dev{inst}; 625db71995Sopenharmony_ci dev.CheckCreate(inst.GetPhysDev()); 635db71995Sopenharmony_ci 645db71995Sopenharmony_ci for (uint32_t j = 0; j < num_loops_try_get_proc_addr; j++) { 655db71995Sopenharmony_ci PFN_vkCmdBindPipeline p = dev.load("vkCmdBindPipeline"); 665db71995Sopenharmony_ci PFN_vkCmdBindDescriptorSets d = dev.load("vkCmdBindDescriptorSets"); 675db71995Sopenharmony_ci PFN_vkCmdBindVertexBuffers vb = dev.load("vkCmdBindVertexBuffers"); 685db71995Sopenharmony_ci PFN_vkCmdBindIndexBuffer ib = dev.load("vkCmdBindIndexBuffer"); 695db71995Sopenharmony_ci PFN_vkCmdDraw c = dev.load("vkCmdDraw"); 705db71995Sopenharmony_ci p(VK_NULL_HANDLE, VkPipelineBindPoint::VK_PIPELINE_BIND_POINT_GRAPHICS, VK_NULL_HANDLE); 715db71995Sopenharmony_ci d(VK_NULL_HANDLE, VkPipelineBindPoint::VK_PIPELINE_BIND_POINT_GRAPHICS, VK_NULL_HANDLE, 0, 0, nullptr, 0, nullptr); 725db71995Sopenharmony_ci vb(VK_NULL_HANDLE, 0, 0, nullptr, nullptr); 735db71995Sopenharmony_ci ib(VK_NULL_HANDLE, 0, 0, VkIndexType::VK_INDEX_TYPE_UINT16); 745db71995Sopenharmony_ci c(VK_NULL_HANDLE, 0, 0, 0, 0); 755db71995Sopenharmony_ci } 765db71995Sopenharmony_ci } 775db71995Sopenharmony_ci} 785db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL test_vkCmdBindPipeline(VkCommandBuffer, VkPipelineBindPoint, VkPipeline) {} 795db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL test_vkCmdBindDescriptorSets(VkCommandBuffer, VkPipelineBindPoint, VkPipelineLayout, uint32_t, uint32_t, 805db71995Sopenharmony_ci const VkDescriptorSet*, uint32_t, const uint32_t*) {} 815db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL test_vkCmdBindVertexBuffers(VkCommandBuffer, uint32_t, uint32_t, const VkBuffer*, const VkDeviceSize*) {} 825db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL test_vkCmdBindIndexBuffer(VkCommandBuffer, uint32_t, uint32_t, const VkBuffer*, const VkDeviceSize*) {} 835db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL test_vkCmdDraw(VkCommandBuffer, uint32_t, uint32_t, uint32_t, uint32_t) {} 845db71995Sopenharmony_ciTEST(Threading, InstanceCreateDestroyLoop) { 855db71995Sopenharmony_ci const auto processor_count = std::thread::hardware_concurrency(); 865db71995Sopenharmony_ci 875db71995Sopenharmony_ci FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("")}; 885db71995Sopenharmony_ci auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 895db71995Sopenharmony_ci uint32_t num_loops_create_destroy_instance = 500; 905db71995Sopenharmony_ci uint32_t num_loops_try_get_instance_proc_addr = 5; 915db71995Sopenharmony_ci uint32_t num_loops_try_get_device_proc_addr = 100; 925db71995Sopenharmony_ci 935db71995Sopenharmony_ci driver.physical_devices.emplace_back("physical_device_0") 945db71995Sopenharmony_ci .known_device_functions.push_back({"vkCmdBindPipeline", to_vkVoidFunction(test_vkCmdBindPipeline)}); 955db71995Sopenharmony_ci 965db71995Sopenharmony_ci std::vector<std::thread> instance_creation_threads; 975db71995Sopenharmony_ci std::vector<std::thread> function_query_threads; 985db71995Sopenharmony_ci for (uint32_t i = 0; i < processor_count; i++) { 995db71995Sopenharmony_ci instance_creation_threads.emplace_back(create_destroy_instance_loop_with_function_queries, &env, 1005db71995Sopenharmony_ci num_loops_create_destroy_instance, num_loops_try_get_instance_proc_addr, 1015db71995Sopenharmony_ci num_loops_try_get_device_proc_addr); 1025db71995Sopenharmony_ci } 1035db71995Sopenharmony_ci for (uint32_t i = 0; i < processor_count; i++) { 1045db71995Sopenharmony_ci instance_creation_threads[i].join(); 1055db71995Sopenharmony_ci } 1065db71995Sopenharmony_ci} 1075db71995Sopenharmony_ci 1085db71995Sopenharmony_ciTEST(Threading, DeviceCreateDestroyLoop) { 1095db71995Sopenharmony_ci const auto processor_count = std::thread::hardware_concurrency(); 1105db71995Sopenharmony_ci 1115db71995Sopenharmony_ci FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("")}; 1125db71995Sopenharmony_ci auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 1135db71995Sopenharmony_ci 1145db71995Sopenharmony_ci uint32_t num_loops_create_destroy_device = 1000; 1155db71995Sopenharmony_ci uint32_t num_loops_try_get_device_proc_addr = 5; 1165db71995Sopenharmony_ci 1175db71995Sopenharmony_ci driver.physical_devices.emplace_back("physical_device_0").known_device_functions = { 1185db71995Sopenharmony_ci {"vkCmdBindPipeline", to_vkVoidFunction(test_vkCmdBindPipeline)}, 1195db71995Sopenharmony_ci {"vkCmdBindDescriptorSets", to_vkVoidFunction(test_vkCmdBindDescriptorSets)}, 1205db71995Sopenharmony_ci {"vkCmdBindVertexBuffers", to_vkVoidFunction(test_vkCmdBindVertexBuffers)}, 1215db71995Sopenharmony_ci {"vkCmdBindIndexBuffer", to_vkVoidFunction(test_vkCmdBindIndexBuffer)}, 1225db71995Sopenharmony_ci {"vkCmdDraw", to_vkVoidFunction(test_vkCmdDraw)}}; 1235db71995Sopenharmony_ci 1245db71995Sopenharmony_ci std::vector<std::thread> device_creation_threads; 1255db71995Sopenharmony_ci 1265db71995Sopenharmony_ci for (uint32_t i = 0; i < processor_count; i++) { 1275db71995Sopenharmony_ci device_creation_threads.emplace_back(create_destroy_device_loop, &env, num_loops_create_destroy_device, 1285db71995Sopenharmony_ci num_loops_try_get_device_proc_addr); 1295db71995Sopenharmony_ci } 1305db71995Sopenharmony_ci for (uint32_t i = 0; i < processor_count; i++) { 1315db71995Sopenharmony_ci device_creation_threads[i].join(); 1325db71995Sopenharmony_ci } 1335db71995Sopenharmony_ci} 134