1 // copyright (c) 2022 the android open source project 2 // 3 // licensed under the apache license, version 2.0 (the "license"); 4 // you may not use this file except in compliance with the license. 5 // you may obtain a copy of the license at 6 // 7 // http://www.apache.org/licenses/license-2.0 8 // 9 // unless required by applicable law or agreed to in writing, software 10 // distributed under the license is distributed on an "as is" basis, 11 // without warranties or conditions of any kind, either express or implied. 12 // see the license for the specific language governing permissions and 13 // limitations under the license. 14 15 #pragma once 16 17 #include "VkDecoderGlobalState.h" 18 #include "VulkanDispatch.h" 19 #include "aemu/base/BumpPool.h" 20 #include "base/include/aemu/base/HealthMonitor.h" 21 #include "base/include/aemu/base/Metrics.h" 22 #include "vulkan/VkCommonOperations.h" 23 #include "vulkan/VkDecoderContext.h" 24 #include "vulkan/testing/VkDecoderTestDispatch.h" 25 #include "utils/include/utils/GfxApiLogger.h" 26 27 namespace gfxstream { 28 namespace vk { 29 namespace testing { 30 31 // This class provides facilities to write tests that call into the Vulkan API through VkDecoder and 32 // VkDecoderGlobalState. 33 // 34 // Usage: 35 // 36 // TEST(MyVulkanTest, Test1) { 37 // VulkanTestHelper vkTest; 38 // vkTest.initialize(); 39 // // then use vkTest.vk() to start calling Vulkan APIs. 40 // } 41 class VulkanTestHelper { 42 public: 43 // Only one instance of this class can exist at a time. (Enforced by locking a mutex on 44 // construction). This is needed because VkDecoderGlobalState is a singleton, so we can't 45 // allow tests to run in parallel. 46 VulkanTestHelper(); 47 48 ~VulkanTestHelper(); 49 50 // Optional parameters for the `initialize()` function 51 struct InitializationOptions { 52 AstcEmulationMode astcLdrEmulationMode; 53 std::optional<VkApplicationInfo> appInfo; 54 VkPhysicalDeviceFeatures deviceFeatures; 55 std::vector<std::string> enabledExtensions; // enabled extensions for vkCreateInstance 56 }; 57 58 void initialize(const InitializationOptions& options = {}); 59 60 // Destroys all the Vulkan objects. This is normally automatically called by the destructor but 61 // can be called manually to allow checking if there are any validation errors at destruction. 62 void destroy(); 63 64 // Whether the test should fail if there were Vulkan validation errors. Defaults to true. failOnValidationErrors(bool value)65 void failOnValidationErrors(bool value) { mFailOnValidationErrors = value; } 66 67 bool hasValidationErrors() const; 68 69 // Vulkan helper functions 70 71 // Starts a command buffer 72 VkCommandBuffer beginCommandBuffer(); 73 74 // Submits a command buffer 75 void submitCommandBuffer(VkCommandBuffer commandBuffer); 76 77 // Gets the index of a queue family that supports the requested queue flags, or aborts. 78 uint32_t getQueueFamilyIndex(VkQueueFlagBits queueFlags); 79 80 uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties); 81 82 // Creates a new VkBuffer and associated memory 83 void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, 84 VkBuffer& buffer, VkDeviceMemory& bufferMemory); 85 86 // Calls vkCmdPipelineBarrier to change an image layout 87 void transitionImageLayout(VkCommandBuffer cmdBuf, VkImage image, VkImageLayout oldLayout, 88 VkImageLayout newLayout); 89 90 // Accessors vk()91 VkDecoderTestDispatch& vk() { return mTestDispatch; } instance()92 VkInstance instance() { return mInstance; } device()93 VkDevice device() { return mDevice; } physDev()94 VkPhysicalDevice physDev() { return mPhysicalDevice; } commandPool()95 VkCommandPool commandPool() { return mCommandPool; } graphicsQueue()96 VkQueue graphicsQueue() { return mGraphicsQueue; } 97 98 private: 99 static std::mutex mMutex; // Locked for the entire lifetime of this class. 100 std::lock_guard<std::mutex> mLock; 101 VulkanDispatch* mVk; 102 emugl::GfxApiLogger mLogger; 103 std::unique_ptr<android::base::MetricsLogger> mMetricsLogger; 104 emugl::HealthMonitor<> mHealthMonitor; 105 VkEmulation* mVkEmu; 106 std::unique_ptr<::android::base::BumpPool> mBp; 107 VkDecoderContext mDecoderContext; 108 VkDecoderTestDispatch mTestDispatch; 109 bool mFailOnValidationErrors = true; 110 111 // Vulkan objects 112 VkInstance mInstance = VK_NULL_HANDLE; 113 VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE; 114 VkDevice mDevice = VK_NULL_HANDLE; 115 VkCommandPool mCommandPool = VK_NULL_HANDLE; 116 VkQueue mGraphicsQueue = VK_NULL_HANDLE; 117 VkDebugUtilsMessengerEXT mDebugMessenger = VK_NULL_HANDLE; 118 }; 119 120 } // namespace testing 121 } // namespace vk 122 } // namespace gfxstream 123