• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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