blob: 1c96c684806e7c08bb4bf0359ead49376e44759a [file] [log] [blame]
// copyright (c) 2022 the android open source project
//
// 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
//
// unless required by applicable law or agreed to in writing, software
// distributed under the license is distributed on an "as is" basis,
// without warranties or conditions of any kind, either express or implied.
// see the license for the specific language governing permissions and
// limitations under the license.
#pragma once
#include "VkDecoderGlobalState.h"
#include "VulkanDispatch.h"
#include "aemu/base/BumpPool.h"
#include "base/include/aemu/base/HealthMonitor.h"
#include "base/include/aemu/base/Metrics.h"
#include "host/vulkan/VkCommonOperations.h"
#include "host/vulkan/VkDecoderContext.h"
#include "host/vulkan/testing/VkDecoderTestDispatch.h"
#include "utils/include/utils/GfxApiLogger.h"
namespace gfxstream {
namespace vk {
namespace testing {
// This class provides facilities to write tests that call into the Vulkan API through VkDecoder and
// VkDecoderGlobalState.
//
// Usage:
//
// TEST(MyVulkanTest, Test1) {
// VulkanTestHelper vkTest;
// vkTest.initialize();
// // then use vkTest.vk() to start calling Vulkan APIs.
// }
class VulkanTestHelper {
public:
// Only one instance of this class can exist at a time. (Enforced by locking a mutex on
// construction). This is needed because VkDecoderGlobalState is a singleton, so we can't
// allow tests to run in parallel.
VulkanTestHelper();
~VulkanTestHelper();
// Optional parameters for the `initialize()` function
struct InitializationOptions {
AstcEmulationMode astcLdrEmulationMode;
std::optional<VkApplicationInfo> appInfo;
VkPhysicalDeviceFeatures deviceFeatures;
std::vector<std::string> enabledExtensions; // enabled extensions for vkCreateInstance
};
void initialize(const InitializationOptions& options = {});
// Destroys all the Vulkan objects. This is normally automatically called by the destructor but
// can be called manually to allow checking if there are any validation errors at destruction.
void destroy();
// Whether the test should fail if there were Vulkan validation errors. Defaults to true.
void failOnValidationErrors(bool value) { mFailOnValidationErrors = value; }
bool hasValidationErrors() const;
// Vulkan helper functions
// Starts a command buffer
VkCommandBuffer beginCommandBuffer();
// Submits a command buffer
void submitCommandBuffer(VkCommandBuffer commandBuffer);
// Gets the index of a queue family that supports the requested queue flags, or aborts.
uint32_t getQueueFamilyIndex(VkQueueFlagBits queueFlags);
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
// Creates a new VkBuffer and associated memory
void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties,
VkBuffer& buffer, VkDeviceMemory& bufferMemory);
// Calls vkCmdPipelineBarrier to change an image layout
void transitionImageLayout(VkCommandBuffer cmdBuf, VkImage image, VkImageLayout oldLayout,
VkImageLayout newLayout);
// Accessors
VkDecoderTestDispatch& vk() { return mTestDispatch; }
VkInstance instance() { return mInstance; }
VkDevice device() { return mDevice; }
VkPhysicalDevice physDev() { return mPhysicalDevice; }
VkCommandPool commandPool() { return mCommandPool; }
VkQueue graphicsQueue() { return mGraphicsQueue; }
private:
static std::mutex mMutex; // Locked for the entire lifetime of this class.
std::lock_guard<std::mutex> mLock;
VulkanDispatch* mVk;
emugl::GfxApiLogger mLogger;
std::unique_ptr<android::base::MetricsLogger> mMetricsLogger;
emugl::HealthMonitor<> mHealthMonitor;
VkEmulation* mVkEmu;
std::unique_ptr<::android::base::BumpPool> mBp;
VkDecoderContext mDecoderContext;
VkDecoderTestDispatch mTestDispatch;
bool mFailOnValidationErrors = true;
// Vulkan objects
VkInstance mInstance = VK_NULL_HANDLE;
VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE;
VkDevice mDevice = VK_NULL_HANDLE;
VkCommandPool mCommandPool = VK_NULL_HANDLE;
VkQueue mGraphicsQueue = VK_NULL_HANDLE;
VkDebugUtilsMessengerEXT mDebugMessenger = VK_NULL_HANDLE;
};
} // namespace testing
} // namespace vk
} // namespace gfxstream