Home | History | Annotate | Download | only in libvulkan
      1 /*
      2  * Copyright 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef LIBVULKAN_DRIVER_H
     18 #define LIBVULKAN_DRIVER_H 1
     19 
     20 #include <inttypes.h>
     21 #include <bitset>
     22 #include <type_traits>
     23 #include <log/log.h>
     24 
     25 #include <vulkan/vulkan.h>
     26 #include <hardware/hwvulkan.h>
     27 
     28 #include "api_gen.h"
     29 #include "driver_gen.h"
     30 #include "debug_report.h"
     31 #include "swapchain.h"
     32 
     33 namespace vulkan {
     34 
     35 // This is here so that we can embed api::{Instance,Device}Data in
     36 // driver::{Instance,Device}Data to avoid pointer chasing.  They are
     37 // considered opaque to the driver layer.
     38 namespace api {
     39 
     40 struct InstanceData {
     41     InstanceDispatchTable dispatch;
     42 
     43     // LayerChain::ActiveLayer array
     44     void* layers;
     45     uint32_t layer_count;
     46 
     47     // debug.vulkan.enable_callback
     48     PFN_vkDestroyDebugReportCallbackEXT destroy_debug_callback;
     49     VkDebugReportCallbackEXT debug_callback;
     50 };
     51 
     52 struct DeviceData {
     53     DeviceDispatchTable dispatch;
     54 };
     55 
     56 }  // namespace api
     57 
     58 namespace driver {
     59 
     60 VK_DEFINE_HANDLE(InstanceDispatchable)
     61 VK_DEFINE_HANDLE(DeviceDispatchable)
     62 
     63 struct InstanceData {
     64     InstanceData(const VkAllocationCallbacks& alloc)
     65         : opaque_api_data(),
     66           allocator(alloc),
     67           driver(),
     68           get_device_proc_addr(nullptr) {
     69         hook_extensions.set(ProcHook::EXTENSION_CORE);
     70     }
     71 
     72     api::InstanceData opaque_api_data;
     73 
     74     const VkAllocationCallbacks allocator;
     75 
     76     std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions;
     77 
     78     InstanceDriverTable driver;
     79     PFN_vkGetDeviceProcAddr get_device_proc_addr;
     80 
     81     DebugReportCallbackList debug_report_callbacks;
     82 };
     83 
     84 struct DeviceData {
     85     DeviceData(const VkAllocationCallbacks& alloc,
     86                const DebugReportCallbackList& debug_report_callbacks_)
     87         : opaque_api_data(),
     88           allocator(alloc),
     89           debug_report_callbacks(debug_report_callbacks_),
     90           driver() {
     91         hook_extensions.set(ProcHook::EXTENSION_CORE);
     92     }
     93 
     94     api::DeviceData opaque_api_data;
     95 
     96     const VkAllocationCallbacks allocator;
     97     const DebugReportCallbackList& debug_report_callbacks;
     98 
     99     std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions;
    100 
    101     VkDevice driver_device;
    102     DeviceDriverTable driver;
    103 };
    104 
    105 bool Debuggable();
    106 bool OpenHAL();
    107 const VkAllocationCallbacks& GetDefaultAllocator();
    108 
    109 // clang-format off
    110 VKAPI_ATTR PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName);
    111 VKAPI_ATTR PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName);
    112 VKAPI_ATTR VkResult EnumerateInstanceExtensionProperties(const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties);
    113 
    114 VKAPI_ATTR VkResult EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties);
    115 
    116 VKAPI_ATTR VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance);
    117 VKAPI_ATTR void DestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator);
    118 VKAPI_ATTR VkResult CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice);
    119 VKAPI_ATTR void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator);
    120 
    121 VKAPI_ATTR VkResult EnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices);
    122 VKAPI_ATTR void GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue);
    123 VKAPI_ATTR VkResult AllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers);
    124 // clang-format on
    125 
    126 template <typename DispatchableType>
    127 void StaticAssertDispatchable(DispatchableType) {
    128     static_assert(
    129         std::is_same<DispatchableType, VkInstance>::value ||
    130             std::is_same<DispatchableType, VkPhysicalDevice>::value ||
    131             std::is_same<DispatchableType, VkDevice>::value ||
    132             std::is_same<DispatchableType, InstanceDispatchable>::value ||
    133             std::is_same<DispatchableType, VkQueue>::value ||
    134             std::is_same<DispatchableType, VkCommandBuffer>::value ||
    135             std::is_same<DispatchableType, DeviceDispatchable>::value,
    136         "unrecognized dispatchable type");
    137 }
    138 
    139 template <typename DispatchableType>
    140 bool SetDataInternal(DispatchableType dispatchable, const void* data) {
    141     StaticAssertDispatchable(dispatchable);
    142 
    143     hwvulkan_dispatch_t* dispatch =
    144         reinterpret_cast<hwvulkan_dispatch_t*>(dispatchable);
    145     // must be magic or already set
    146     if (dispatch->magic != HWVULKAN_DISPATCH_MAGIC && dispatch->vtbl != data) {
    147         ALOGE("invalid dispatchable object magic 0x%" PRIxPTR, dispatch->magic);
    148         return false;
    149     }
    150 
    151     dispatch->vtbl = data;
    152 
    153     return true;
    154 }
    155 
    156 template <typename DispatchableType>
    157 void* GetDataInternal(DispatchableType dispatchable) {
    158     StaticAssertDispatchable(dispatchable);
    159 
    160     const hwvulkan_dispatch_t* dispatch =
    161         reinterpret_cast<const hwvulkan_dispatch_t*>(dispatchable);
    162 
    163     return const_cast<void*>(dispatch->vtbl);
    164 }
    165 
    166 inline bool SetData(VkInstance instance, const InstanceData& data) {
    167     return SetDataInternal(instance, &data);
    168 }
    169 
    170 inline bool SetData(VkPhysicalDevice physical_dev, const InstanceData& data) {
    171     return SetDataInternal(physical_dev, &data);
    172 }
    173 
    174 inline bool SetData(InstanceDispatchable dispatchable,
    175                     const InstanceData& data) {
    176     return SetDataInternal(dispatchable, &data);
    177 }
    178 
    179 inline bool SetData(VkDevice dev, const DeviceData& data) {
    180     return SetDataInternal(dev, &data);
    181 }
    182 
    183 inline bool SetData(VkQueue queue, const DeviceData& data) {
    184     return SetDataInternal(queue, &data);
    185 }
    186 
    187 inline bool SetData(VkCommandBuffer cmd, const DeviceData& data) {
    188     return SetDataInternal(cmd, &data);
    189 }
    190 
    191 inline bool SetData(DeviceDispatchable dispatchable, const DeviceData& data) {
    192     return SetDataInternal(dispatchable, &data);
    193 }
    194 
    195 inline InstanceData& GetData(VkInstance instance) {
    196     return *reinterpret_cast<InstanceData*>(GetDataInternal(instance));
    197 }
    198 
    199 inline InstanceData& GetData(VkPhysicalDevice physical_dev) {
    200     return *reinterpret_cast<InstanceData*>(GetDataInternal(physical_dev));
    201 }
    202 
    203 inline InstanceData& GetData(InstanceDispatchable dispatchable) {
    204     return *reinterpret_cast<InstanceData*>(GetDataInternal(dispatchable));
    205 }
    206 
    207 inline DeviceData& GetData(VkDevice dev) {
    208     return *reinterpret_cast<DeviceData*>(GetDataInternal(dev));
    209 }
    210 
    211 inline DeviceData& GetData(VkQueue queue) {
    212     return *reinterpret_cast<DeviceData*>(GetDataInternal(queue));
    213 }
    214 
    215 inline DeviceData& GetData(VkCommandBuffer cmd) {
    216     return *reinterpret_cast<DeviceData*>(GetDataInternal(cmd));
    217 }
    218 
    219 inline DeviceData& GetData(DeviceDispatchable dispatchable) {
    220     return *reinterpret_cast<DeviceData*>(GetDataInternal(dispatchable));
    221 }
    222 
    223 template <typename DispatchableType>
    224 const DebugReportLogger Logger(DispatchableType dispatchable) {
    225     return DebugReportLogger(GetData(dispatchable).debug_report_callbacks);
    226 }
    227 
    228 }  // namespace driver
    229 }  // namespace vulkan
    230 
    231 #endif  // LIBVULKAN_DRIVER_H
    232