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