xref: /aosp_15_r20/frameworks/native/vulkan/libvulkan/stubhal.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2016 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker /* NOTE:
18*38e8c45fSAndroid Build Coastguard Worker  * This stub HAL is only used internally by the loader when a real HAL
19*38e8c45fSAndroid Build Coastguard Worker  * implementation is not present, in order to avoid needing "null HAL" checks
20*38e8c45fSAndroid Build Coastguard Worker  * throughout the loader. It does not enumerate any physical devices, and is
21*38e8c45fSAndroid Build Coastguard Worker  * only as conformant to the Vulkan and Android HAL interfaces as the loader
22*38e8c45fSAndroid Build Coastguard Worker  * needs it to be. Do not use it as an example of a correct implementation; the
23*38e8c45fSAndroid Build Coastguard Worker  * code in ../null_driver is better for that.
24*38e8c45fSAndroid Build Coastguard Worker  */
25*38e8c45fSAndroid Build Coastguard Worker 
26*38e8c45fSAndroid Build Coastguard Worker #undef LOG_TAG
27*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "vkstub"
28*38e8c45fSAndroid Build Coastguard Worker 
29*38e8c45fSAndroid Build Coastguard Worker #include <array>
30*38e8c45fSAndroid Build Coastguard Worker #include <bitset>
31*38e8c45fSAndroid Build Coastguard Worker #include <mutex>
32*38e8c45fSAndroid Build Coastguard Worker 
33*38e8c45fSAndroid Build Coastguard Worker #include <log/log.h>
34*38e8c45fSAndroid Build Coastguard Worker #include <hardware/hwvulkan.h>
35*38e8c45fSAndroid Build Coastguard Worker 
36*38e8c45fSAndroid Build Coastguard Worker #include "stubhal.h"
37*38e8c45fSAndroid Build Coastguard Worker 
38*38e8c45fSAndroid Build Coastguard Worker namespace vulkan {
39*38e8c45fSAndroid Build Coastguard Worker namespace stubhal {
40*38e8c45fSAndroid Build Coastguard Worker 
41*38e8c45fSAndroid Build Coastguard Worker namespace {
42*38e8c45fSAndroid Build Coastguard Worker 
43*38e8c45fSAndroid Build Coastguard Worker const size_t kMaxInstances = 32;
44*38e8c45fSAndroid Build Coastguard Worker static std::mutex g_instance_mutex;
45*38e8c45fSAndroid Build Coastguard Worker static std::bitset<kMaxInstances> g_instance_used(false);
46*38e8c45fSAndroid Build Coastguard Worker static std::array<hwvulkan_dispatch_t, kMaxInstances> g_instances;
47*38e8c45fSAndroid Build Coastguard Worker 
NoOp()48*38e8c45fSAndroid Build Coastguard Worker [[noreturn]] VKAPI_ATTR void NoOp() {
49*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL("invalid stub function called");
50*38e8c45fSAndroid Build Coastguard Worker }
51*38e8c45fSAndroid Build Coastguard Worker 
52*38e8c45fSAndroid Build Coastguard Worker VKAPI_ATTR VkResult
EnumerateInstanceExtensionProperties(const char *,uint32_t * count,VkExtensionProperties *)53*38e8c45fSAndroid Build Coastguard Worker EnumerateInstanceExtensionProperties(const char* /*layer_name*/,
54*38e8c45fSAndroid Build Coastguard Worker                                      uint32_t* count,
55*38e8c45fSAndroid Build Coastguard Worker                                      VkExtensionProperties* /*properties*/) {
56*38e8c45fSAndroid Build Coastguard Worker     *count = 0;
57*38e8c45fSAndroid Build Coastguard Worker     return VK_SUCCESS;
58*38e8c45fSAndroid Build Coastguard Worker }
59*38e8c45fSAndroid Build Coastguard Worker 
60*38e8c45fSAndroid Build Coastguard Worker VKAPI_ATTR VkResult
EnumerateInstanceLayerProperties(uint32_t * count,VkLayerProperties *)61*38e8c45fSAndroid Build Coastguard Worker EnumerateInstanceLayerProperties(uint32_t* count,
62*38e8c45fSAndroid Build Coastguard Worker                                  VkLayerProperties* /*properties*/) {
63*38e8c45fSAndroid Build Coastguard Worker     *count = 0;
64*38e8c45fSAndroid Build Coastguard Worker     return VK_SUCCESS;
65*38e8c45fSAndroid Build Coastguard Worker }
66*38e8c45fSAndroid Build Coastguard Worker 
CreateInstance(const VkInstanceCreateInfo *,const VkAllocationCallbacks *,VkInstance * instance)67*38e8c45fSAndroid Build Coastguard Worker VKAPI_ATTR VkResult CreateInstance(const VkInstanceCreateInfo* /*create_info*/,
68*38e8c45fSAndroid Build Coastguard Worker                                    const VkAllocationCallbacks* /*allocator*/,
69*38e8c45fSAndroid Build Coastguard Worker                                    VkInstance* instance) {
70*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(g_instance_mutex);
71*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < kMaxInstances; i++) {
72*38e8c45fSAndroid Build Coastguard Worker         if (!g_instance_used[i]) {
73*38e8c45fSAndroid Build Coastguard Worker             g_instance_used[i] = true;
74*38e8c45fSAndroid Build Coastguard Worker             g_instances[i].magic = HWVULKAN_DISPATCH_MAGIC;
75*38e8c45fSAndroid Build Coastguard Worker             *instance = reinterpret_cast<VkInstance>(&g_instances[i]);
76*38e8c45fSAndroid Build Coastguard Worker             return VK_SUCCESS;
77*38e8c45fSAndroid Build Coastguard Worker         }
78*38e8c45fSAndroid Build Coastguard Worker     }
79*38e8c45fSAndroid Build Coastguard Worker     ALOGE("no more instances available (max=%zu)", kMaxInstances);
80*38e8c45fSAndroid Build Coastguard Worker     return VK_ERROR_INITIALIZATION_FAILED;
81*38e8c45fSAndroid Build Coastguard Worker }
82*38e8c45fSAndroid Build Coastguard Worker 
DestroyInstance(VkInstance instance,const VkAllocationCallbacks *)83*38e8c45fSAndroid Build Coastguard Worker VKAPI_ATTR void DestroyInstance(VkInstance instance,
84*38e8c45fSAndroid Build Coastguard Worker                                 const VkAllocationCallbacks* /*allocator*/) {
85*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(g_instance_mutex);
86*38e8c45fSAndroid Build Coastguard Worker     ssize_t idx =
87*38e8c45fSAndroid Build Coastguard Worker         reinterpret_cast<hwvulkan_dispatch_t*>(instance) - &g_instances[0];
88*38e8c45fSAndroid Build Coastguard Worker     ALOG_ASSERT(idx >= 0 && static_cast<size_t>(idx) < g_instance_used.size(),
89*38e8c45fSAndroid Build Coastguard Worker                 "DestroyInstance: invalid instance handle");
90*38e8c45fSAndroid Build Coastguard Worker     g_instance_used[static_cast<size_t>(idx)] = false;
91*38e8c45fSAndroid Build Coastguard Worker }
92*38e8c45fSAndroid Build Coastguard Worker 
EnumeratePhysicalDevices(VkInstance,uint32_t * count,VkPhysicalDevice *)93*38e8c45fSAndroid Build Coastguard Worker VKAPI_ATTR VkResult EnumeratePhysicalDevices(VkInstance /*instance*/,
94*38e8c45fSAndroid Build Coastguard Worker                                              uint32_t* count,
95*38e8c45fSAndroid Build Coastguard Worker                                              VkPhysicalDevice* /*gpus*/) {
96*38e8c45fSAndroid Build Coastguard Worker     *count = 0;
97*38e8c45fSAndroid Build Coastguard Worker     return VK_SUCCESS;
98*38e8c45fSAndroid Build Coastguard Worker }
99*38e8c45fSAndroid Build Coastguard Worker 
100*38e8c45fSAndroid Build Coastguard Worker VKAPI_ATTR VkResult
EnumeratePhysicalDeviceGroups(VkInstance,uint32_t * count,VkPhysicalDeviceGroupProperties *)101*38e8c45fSAndroid Build Coastguard Worker EnumeratePhysicalDeviceGroups(VkInstance /*instance*/,
102*38e8c45fSAndroid Build Coastguard Worker                               uint32_t* count,
103*38e8c45fSAndroid Build Coastguard Worker                               VkPhysicalDeviceGroupProperties* /*properties*/) {
104*38e8c45fSAndroid Build Coastguard Worker     *count = 0;
105*38e8c45fSAndroid Build Coastguard Worker     return VK_SUCCESS;
106*38e8c45fSAndroid Build Coastguard Worker }
107*38e8c45fSAndroid Build Coastguard Worker 
GetInstanceProcAddr(VkInstance instance,const char * name)108*38e8c45fSAndroid Build Coastguard Worker VKAPI_ATTR PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance,
109*38e8c45fSAndroid Build Coastguard Worker                                                   const char* name) {
110*38e8c45fSAndroid Build Coastguard Worker     if (strcmp(name, "vkCreateInstance") == 0)
111*38e8c45fSAndroid Build Coastguard Worker         return reinterpret_cast<PFN_vkVoidFunction>(CreateInstance);
112*38e8c45fSAndroid Build Coastguard Worker     if (strcmp(name, "vkDestroyInstance") == 0)
113*38e8c45fSAndroid Build Coastguard Worker         return reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance);
114*38e8c45fSAndroid Build Coastguard Worker     if (strcmp(name, "vkEnumerateInstanceExtensionProperties") == 0)
115*38e8c45fSAndroid Build Coastguard Worker         return reinterpret_cast<PFN_vkVoidFunction>(
116*38e8c45fSAndroid Build Coastguard Worker             EnumerateInstanceExtensionProperties);
117*38e8c45fSAndroid Build Coastguard Worker     if (strcmp(name, "vkEnumeratePhysicalDevices") == 0)
118*38e8c45fSAndroid Build Coastguard Worker         return reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices);
119*38e8c45fSAndroid Build Coastguard Worker     if (strcmp(name, "vkEnumeratePhysicalDeviceGroups") == 0)
120*38e8c45fSAndroid Build Coastguard Worker         return reinterpret_cast<PFN_vkVoidFunction>(
121*38e8c45fSAndroid Build Coastguard Worker             EnumeratePhysicalDeviceGroups);
122*38e8c45fSAndroid Build Coastguard Worker     if (strcmp(name, "vkGetInstanceProcAddr") == 0)
123*38e8c45fSAndroid Build Coastguard Worker         return reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr);
124*38e8c45fSAndroid Build Coastguard Worker     // Per the spec, return NULL if instance is NULL.
125*38e8c45fSAndroid Build Coastguard Worker     if (!instance)
126*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
127*38e8c45fSAndroid Build Coastguard Worker     // None of the other Vulkan functions should ever be called, as they all
128*38e8c45fSAndroid Build Coastguard Worker     // take a VkPhysicalDevice or other object obtained from a physical device.
129*38e8c45fSAndroid Build Coastguard Worker     return reinterpret_cast<PFN_vkVoidFunction>(NoOp);
130*38e8c45fSAndroid Build Coastguard Worker }
131*38e8c45fSAndroid Build Coastguard Worker 
132*38e8c45fSAndroid Build Coastguard Worker }  // anonymous namespace
133*38e8c45fSAndroid Build Coastguard Worker 
134*38e8c45fSAndroid Build Coastguard Worker const hwvulkan_device_t kDevice = {
135*38e8c45fSAndroid Build Coastguard Worker     .common =
136*38e8c45fSAndroid Build Coastguard Worker         {
137*38e8c45fSAndroid Build Coastguard Worker             .tag = HARDWARE_DEVICE_TAG,
138*38e8c45fSAndroid Build Coastguard Worker             .version = HWVULKAN_DEVICE_API_VERSION_0_1,
139*38e8c45fSAndroid Build Coastguard Worker             .module = nullptr,
140*38e8c45fSAndroid Build Coastguard Worker             .close = nullptr,
141*38e8c45fSAndroid Build Coastguard Worker         },
142*38e8c45fSAndroid Build Coastguard Worker     .EnumerateInstanceExtensionProperties =
143*38e8c45fSAndroid Build Coastguard Worker         EnumerateInstanceExtensionProperties,
144*38e8c45fSAndroid Build Coastguard Worker     .CreateInstance = CreateInstance,
145*38e8c45fSAndroid Build Coastguard Worker     .GetInstanceProcAddr = GetInstanceProcAddr,
146*38e8c45fSAndroid Build Coastguard Worker };
147*38e8c45fSAndroid Build Coastguard Worker 
148*38e8c45fSAndroid Build Coastguard Worker }  // namespace stubhal
149*38e8c45fSAndroid Build Coastguard Worker }  // namespace vulkan
150