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