vulkan: initial loader and null driver
Change-Id: Id5ebb5f01e61e9b114990f49c64c88fbbb7b730e
(cherry picked from commit 4df205cdfc61e66de774ba50be9ef59a08cf88bb)
diff --git a/vulkan/libvulkan/Android.mk b/vulkan/libvulkan/Android.mk
new file mode 100644
index 0000000..c26b01f
--- /dev/null
+++ b/vulkan/libvulkan/Android.mk
@@ -0,0 +1,25 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_CLANG := true
+LOCAL_CFLAGS := -std=c99 -fvisibility=hidden -fstrict-aliasing
+LOCAL_CFLAGS += -DLOG_TAG=\"vulkan\"
+LOCAL_CFLAGS += -Weverything -Werror -Wno-padded -Wno-undef
+LOCAL_CPPFLAGS := -std=c++1y \
+ -Wno-c++98-compat-pedantic \
+ -Wno-exit-time-destructors \
+ -Wno-c99-extensions
+
+LOCAL_C_INCLUDES := \
+ frameworks/native/vulkan/include
+
+LOCAL_SRC_FILES := \
+ entry.cpp \
+ get_proc_addr.cpp \
+ loader.cpp
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
+LOCAL_SHARED_LIBRARIES := libhardware liblog
+
+LOCAL_MODULE := libvulkan
+include $(BUILD_SHARED_LIBRARY)
diff --git a/vulkan/libvulkan/entry.cpp b/vulkan/libvulkan/entry.cpp
new file mode 100644
index 0000000..7bfaaf2
--- /dev/null
+++ b/vulkan/libvulkan/entry.cpp
@@ -0,0 +1,802 @@
+/*
+* Copyright 2015 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.
+*/
+
+// This file is generated. Do not edit manually!
+// To regenerate: $ apic template ../api/vulkan.api entry.cpp.tmpl
+// Requires apic from https://android.googlesource.com/platform/tools/gpu/.
+
+#include "loader.h"
+using namespace vulkan;
+
+// clang-format off
+
+namespace {
+ inline const InstanceVtbl& GetVtbl(VkInstance instance) {
+ return **reinterpret_cast<InstanceVtbl**>(instance);
+ }
+ inline const InstanceVtbl& GetVtbl(VkPhysicalDevice physicalDevice) {
+ return **reinterpret_cast<InstanceVtbl**>(physicalDevice);
+ }
+ inline const DeviceVtbl& GetVtbl(VkDevice device) {
+ return **reinterpret_cast<DeviceVtbl**>(device);
+ }
+ inline const DeviceVtbl& GetVtbl(VkQueue queue) {
+ return **reinterpret_cast<DeviceVtbl**>(queue);
+ }
+ inline const DeviceVtbl& GetVtbl(VkCmdBuffer cmdBuffer) {
+ return **reinterpret_cast<DeviceVtbl**>(cmdBuffer);
+ }
+} // namespace
+
+__attribute__((visibility("default")))
+VkResult vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, VkInstance* pInstance) {
+ return vulkan::CreateInstance(pCreateInfo, pInstance);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyInstance(VkInstance instance) {
+ return GetVtbl(instance).DestroyInstance(instance);
+}
+
+__attribute__((visibility("default")))
+VkResult vkEnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices) {
+ return GetVtbl(instance).EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
+}
+
+__attribute__((visibility("default")))
+PFN_vkVoidFunction vkGetDeviceProcAddr(VkDevice device, const char* pName) {
+ return vulkan::GetDeviceProcAddr(device, pName);
+}
+
+__attribute__((visibility("default")))
+PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance instance, const char* pName) {
+ return vulkan::GetInstanceProcAddr(instance, pName);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties) {
+ return GetVtbl(physicalDevice).GetPhysicalDeviceProperties(physicalDevice, pProperties);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetPhysicalDeviceQueueCount(VkPhysicalDevice physicalDevice, uint32_t* pCount) {
+ return GetVtbl(physicalDevice).GetPhysicalDeviceQueueCount(physicalDevice, pCount);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetPhysicalDeviceQueueProperties(VkPhysicalDevice physicalDevice, uint32_t count, VkPhysicalDeviceQueueProperties* pQueueProperties) {
+ return GetVtbl(physicalDevice).GetPhysicalDeviceQueueProperties(physicalDevice, count, pQueueProperties);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties) {
+ return GetVtbl(physicalDevice).GetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures) {
+ return GetVtbl(physicalDevice).GetPhysicalDeviceFeatures(physicalDevice, pFeatures);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties* pFormatProperties) {
+ return GetVtbl(physicalDevice).GetPhysicalDeviceFormatProperties(physicalDevice, format, pFormatProperties);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageFormatProperties* pImageFormatProperties) {
+ return GetVtbl(physicalDevice).GetPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, pImageFormatProperties);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetPhysicalDeviceLimits(VkPhysicalDevice physicalDevice, VkPhysicalDeviceLimits* pLimits) {
+ return GetVtbl(physicalDevice).GetPhysicalDeviceLimits(physicalDevice, pLimits);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, VkDevice* pDevice) {
+ return GetVtbl(physicalDevice).CreateDevice(physicalDevice, pCreateInfo, pDevice);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyDevice(VkDevice device) {
+ return vulkan::DestroyDevice(device);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetGlobalLayerProperties(uint32_t* pCount, VkLayerProperties* pProperties) {
+ return vulkan::GetGlobalLayerProperties(pCount, pProperties);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetGlobalExtensionProperties(const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties) {
+ return vulkan::GetGlobalExtensionProperties(pLayerName, pCount, pProperties);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetPhysicalDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t* pCount, VkLayerProperties* pProperties) {
+ return GetVtbl(physicalDevice).GetPhysicalDeviceLayerProperties(physicalDevice, pCount, pProperties);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetPhysicalDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties) {
+ return GetVtbl(physicalDevice).GetPhysicalDeviceExtensionProperties(physicalDevice, pLayerName, pCount, pProperties);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue) {
+ return vulkan::GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
+}
+
+__attribute__((visibility("default")))
+VkResult vkQueueSubmit(VkQueue queue, uint32_t cmdBufferCount, const VkCmdBuffer* pCmdBuffers, VkFence fence) {
+ return GetVtbl(queue).QueueSubmit(queue, cmdBufferCount, pCmdBuffers, fence);
+}
+
+__attribute__((visibility("default")))
+VkResult vkQueueWaitIdle(VkQueue queue) {
+ return GetVtbl(queue).QueueWaitIdle(queue);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDeviceWaitIdle(VkDevice device) {
+ return GetVtbl(device).DeviceWaitIdle(device);
+}
+
+__attribute__((visibility("default")))
+VkResult vkAllocMemory(VkDevice device, const VkMemoryAllocInfo* pAllocInfo, VkDeviceMemory* pMem) {
+ return GetVtbl(device).AllocMemory(device, pAllocInfo, pMem);
+}
+
+__attribute__((visibility("default")))
+VkResult vkFreeMemory(VkDevice device, VkDeviceMemory mem) {
+ return GetVtbl(device).FreeMemory(device, mem);
+}
+
+__attribute__((visibility("default")))
+VkResult vkMapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData) {
+ return GetVtbl(device).MapMemory(device, mem, offset, size, flags, ppData);
+}
+
+__attribute__((visibility("default")))
+VkResult vkUnmapMemory(VkDevice device, VkDeviceMemory mem) {
+ return GetVtbl(device).UnmapMemory(device, mem);
+}
+
+__attribute__((visibility("default")))
+VkResult vkFlushMappedMemoryRanges(VkDevice device, uint32_t memRangeCount, const VkMappedMemoryRange* pMemRanges) {
+ return GetVtbl(device).FlushMappedMemoryRanges(device, memRangeCount, pMemRanges);
+}
+
+__attribute__((visibility("default")))
+VkResult vkInvalidateMappedMemoryRanges(VkDevice device, uint32_t memRangeCount, const VkMappedMemoryRange* pMemRanges) {
+ return GetVtbl(device).InvalidateMappedMemoryRanges(device, memRangeCount, pMemRanges);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetDeviceMemoryCommitment(VkDevice device, VkDeviceMemory memory, VkDeviceSize* pCommittedMemoryInBytes) {
+ return GetVtbl(device).GetDeviceMemoryCommitment(device, memory, pCommittedMemoryInBytes);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer, VkMemoryRequirements* pMemoryRequirements) {
+ return GetVtbl(device).GetBufferMemoryRequirements(device, buffer, pMemoryRequirements);
+}
+
+__attribute__((visibility("default")))
+VkResult vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset) {
+ return GetVtbl(device).BindBufferMemory(device, buffer, mem, memOffset);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetImageMemoryRequirements(VkDevice device, VkImage image, VkMemoryRequirements* pMemoryRequirements) {
+ return GetVtbl(device).GetImageMemoryRequirements(device, image, pMemoryRequirements);
+}
+
+__attribute__((visibility("default")))
+VkResult vkBindImageMemory(VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset) {
+ return GetVtbl(device).BindImageMemory(device, image, mem, memOffset);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetImageSparseMemoryRequirements(VkDevice device, VkImage image, uint32_t* pNumRequirements, VkSparseImageMemoryRequirements* pSparseMemoryRequirements) {
+ return GetVtbl(device).GetImageSparseMemoryRequirements(device, image, pNumRequirements, pSparseMemoryRequirements);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, uint32_t samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pNumProperties, VkSparseImageFormatProperties* pProperties) {
+ return GetVtbl(physicalDevice).GetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, pNumProperties, pProperties);
+}
+
+__attribute__((visibility("default")))
+VkResult vkQueueBindSparseBufferMemory(VkQueue queue, VkBuffer buffer, uint32_t numBindings, const VkSparseMemoryBindInfo* pBindInfo) {
+ return GetVtbl(queue).QueueBindSparseBufferMemory(queue, buffer, numBindings, pBindInfo);
+}
+
+__attribute__((visibility("default")))
+VkResult vkQueueBindSparseImageOpaqueMemory(VkQueue queue, VkImage image, uint32_t numBindings, const VkSparseMemoryBindInfo* pBindInfo) {
+ return GetVtbl(queue).QueueBindSparseImageOpaqueMemory(queue, image, numBindings, pBindInfo);
+}
+
+__attribute__((visibility("default")))
+VkResult vkQueueBindSparseImageMemory(VkQueue queue, VkImage image, uint32_t numBindings, const VkSparseImageMemoryBindInfo* pBindInfo) {
+ return GetVtbl(queue).QueueBindSparseImageMemory(queue, image, numBindings, pBindInfo);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateFence(VkDevice device, const VkFenceCreateInfo* pCreateInfo, VkFence* pFence) {
+ return GetVtbl(device).CreateFence(device, pCreateInfo, pFence);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyFence(VkDevice device, VkFence fence) {
+ return GetVtbl(device).DestroyFence(device, fence);
+}
+
+__attribute__((visibility("default")))
+VkResult vkResetFences(VkDevice device, uint32_t fenceCount, const VkFence* pFences) {
+ return GetVtbl(device).ResetFences(device, fenceCount, pFences);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetFenceStatus(VkDevice device, VkFence fence) {
+ return GetVtbl(device).GetFenceStatus(device, fence);
+}
+
+__attribute__((visibility("default")))
+VkResult vkWaitForFences(VkDevice device, uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout) {
+ return GetVtbl(device).WaitForFences(device, fenceCount, pFences, waitAll, timeout);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo, VkSemaphore* pSemaphore) {
+ return GetVtbl(device).CreateSemaphore(device, pCreateInfo, pSemaphore);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroySemaphore(VkDevice device, VkSemaphore semaphore) {
+ return GetVtbl(device).DestroySemaphore(device, semaphore);
+}
+
+__attribute__((visibility("default")))
+VkResult vkQueueSignalSemaphore(VkQueue queue, VkSemaphore semaphore) {
+ return GetVtbl(queue).QueueSignalSemaphore(queue, semaphore);
+}
+
+__attribute__((visibility("default")))
+VkResult vkQueueWaitSemaphore(VkQueue queue, VkSemaphore semaphore) {
+ return GetVtbl(queue).QueueWaitSemaphore(queue, semaphore);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateEvent(VkDevice device, const VkEventCreateInfo* pCreateInfo, VkEvent* pEvent) {
+ return GetVtbl(device).CreateEvent(device, pCreateInfo, pEvent);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyEvent(VkDevice device, VkEvent event) {
+ return GetVtbl(device).DestroyEvent(device, event);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetEventStatus(VkDevice device, VkEvent event) {
+ return GetVtbl(device).GetEventStatus(device, event);
+}
+
+__attribute__((visibility("default")))
+VkResult vkSetEvent(VkDevice device, VkEvent event) {
+ return GetVtbl(device).SetEvent(device, event);
+}
+
+__attribute__((visibility("default")))
+VkResult vkResetEvent(VkDevice device, VkEvent event) {
+ return GetVtbl(device).ResetEvent(device, event);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo, VkQueryPool* pQueryPool) {
+ return GetVtbl(device).CreateQueryPool(device, pCreateInfo, pQueryPool);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyQueryPool(VkDevice device, VkQueryPool queryPool) {
+ return GetVtbl(device).DestroyQueryPool(device, queryPool);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t startQuery, uint32_t queryCount, size_t* pDataSize, void* pData, VkQueryResultFlags flags) {
+ return GetVtbl(device).GetQueryPoolResults(device, queryPool, startQuery, queryCount, pDataSize, pData, flags);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateBuffer(VkDevice device, const VkBufferCreateInfo* pCreateInfo, VkBuffer* pBuffer) {
+ return GetVtbl(device).CreateBuffer(device, pCreateInfo, pBuffer);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyBuffer(VkDevice device, VkBuffer buffer) {
+ return GetVtbl(device).DestroyBuffer(device, buffer);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateBufferView(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, VkBufferView* pView) {
+ return GetVtbl(device).CreateBufferView(device, pCreateInfo, pView);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyBufferView(VkDevice device, VkBufferView bufferView) {
+ return GetVtbl(device).DestroyBufferView(device, bufferView);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, VkImage* pImage) {
+ return GetVtbl(device).CreateImage(device, pCreateInfo, pImage);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyImage(VkDevice device, VkImage image) {
+ return GetVtbl(device).DestroyImage(device, image);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetImageSubresourceLayout(VkDevice device, VkImage image, const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout) {
+ return GetVtbl(device).GetImageSubresourceLayout(device, image, pSubresource, pLayout);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, VkImageView* pView) {
+ return GetVtbl(device).CreateImageView(device, pCreateInfo, pView);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyImageView(VkDevice device, VkImageView imageView) {
+ return GetVtbl(device).DestroyImageView(device, imageView);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateAttachmentView(VkDevice device, const VkAttachmentViewCreateInfo* pCreateInfo, VkAttachmentView* pView) {
+ return GetVtbl(device).CreateAttachmentView(device, pCreateInfo, pView);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyAttachmentView(VkDevice device, VkAttachmentView attachmentView) {
+ return GetVtbl(device).DestroyAttachmentView(device, attachmentView);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, VkShaderModule* pShaderModule) {
+ return GetVtbl(device).CreateShaderModule(device, pCreateInfo, pShaderModule);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule) {
+ return GetVtbl(device).DestroyShaderModule(device, shaderModule);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateShader(VkDevice device, const VkShaderCreateInfo* pCreateInfo, VkShader* pShader) {
+ return GetVtbl(device).CreateShader(device, pCreateInfo, pShader);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyShader(VkDevice device, VkShader shader) {
+ return GetVtbl(device).DestroyShader(device, shader);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreatePipelineCache(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, VkPipelineCache* pPipelineCache) {
+ return GetVtbl(device).CreatePipelineCache(device, pCreateInfo, pPipelineCache);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache) {
+ return GetVtbl(device).DestroyPipelineCache(device, pipelineCache);
+}
+
+__attribute__((visibility("default")))
+size_t vkGetPipelineCacheSize(VkDevice device, VkPipelineCache pipelineCache) {
+ return GetVtbl(device).GetPipelineCacheSize(device, pipelineCache);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, void* pData) {
+ return GetVtbl(device).GetPipelineCacheData(device, pipelineCache, pData);
+}
+
+__attribute__((visibility("default")))
+VkResult vkMergePipelineCaches(VkDevice device, VkPipelineCache destCache, uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches) {
+ return GetVtbl(device).MergePipelineCaches(device, destCache, srcCacheCount, pSrcCaches);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count, const VkGraphicsPipelineCreateInfo* pCreateInfos, VkPipeline* pPipelines) {
+ return GetVtbl(device).CreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pPipelines);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count, const VkComputePipelineCreateInfo* pCreateInfos, VkPipeline* pPipelines) {
+ return GetVtbl(device).CreateComputePipelines(device, pipelineCache, count, pCreateInfos, pPipelines);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyPipeline(VkDevice device, VkPipeline pipeline) {
+ return GetVtbl(device).DestroyPipeline(device, pipeline);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, VkPipelineLayout* pPipelineLayout) {
+ return GetVtbl(device).CreatePipelineLayout(device, pCreateInfo, pPipelineLayout);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout) {
+ return GetVtbl(device).DestroyPipelineLayout(device, pipelineLayout);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, VkSampler* pSampler) {
+ return GetVtbl(device).CreateSampler(device, pCreateInfo, pSampler);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroySampler(VkDevice device, VkSampler sampler) {
+ return GetVtbl(device).DestroySampler(device, sampler);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayout* pSetLayout) {
+ return GetVtbl(device).CreateDescriptorSetLayout(device, pCreateInfo, pSetLayout);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout) {
+ return GetVtbl(device).DestroyDescriptorSetLayout(device, descriptorSetLayout);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateDescriptorPool(VkDevice device, VkDescriptorPoolUsage poolUsage, uint32_t maxSets, const VkDescriptorPoolCreateInfo* pCreateInfo, VkDescriptorPool* pDescriptorPool) {
+ return GetVtbl(device).CreateDescriptorPool(device, poolUsage, maxSets, pCreateInfo, pDescriptorPool);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool) {
+ return GetVtbl(device).DestroyDescriptorPool(device, descriptorPool);
+}
+
+__attribute__((visibility("default")))
+VkResult vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool) {
+ return GetVtbl(device).ResetDescriptorPool(device, descriptorPool);
+}
+
+__attribute__((visibility("default")))
+VkResult vkAllocDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSetUsage setUsage, uint32_t count, const VkDescriptorSetLayout* pSetLayouts, VkDescriptorSet* pDescriptorSets, uint32_t* pCount) {
+ return GetVtbl(device).AllocDescriptorSets(device, descriptorPool, setUsage, count, pSetLayouts, pDescriptorSets, pCount);
+}
+
+__attribute__((visibility("default")))
+VkResult vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count, const VkDescriptorSet* pDescriptorSets) {
+ return GetVtbl(device).FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
+}
+
+__attribute__((visibility("default")))
+VkResult vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t copyCount, const VkCopyDescriptorSet* pDescriptorCopies) {
+ return GetVtbl(device).UpdateDescriptorSets(device, writeCount, pDescriptorWrites, copyCount, pDescriptorCopies);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateDynamicViewportState(VkDevice device, const VkDynamicViewportStateCreateInfo* pCreateInfo, VkDynamicViewportState* pState) {
+ return GetVtbl(device).CreateDynamicViewportState(device, pCreateInfo, pState);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyDynamicViewportState(VkDevice device, VkDynamicViewportState dynamicViewportState) {
+ return GetVtbl(device).DestroyDynamicViewportState(device, dynamicViewportState);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateDynamicRasterState(VkDevice device, const VkDynamicRasterStateCreateInfo* pCreateInfo, VkDynamicRasterState* pState) {
+ return GetVtbl(device).CreateDynamicRasterState(device, pCreateInfo, pState);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyDynamicRasterState(VkDevice device, VkDynamicRasterState dynamicRasterState) {
+ return GetVtbl(device).DestroyDynamicRasterState(device, dynamicRasterState);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateDynamicColorBlendState(VkDevice device, const VkDynamicColorBlendStateCreateInfo* pCreateInfo, VkDynamicColorBlendState* pState) {
+ return GetVtbl(device).CreateDynamicColorBlendState(device, pCreateInfo, pState);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyDynamicColorBlendState(VkDevice device, VkDynamicColorBlendState dynamicColorBlendState) {
+ return GetVtbl(device).DestroyDynamicColorBlendState(device, dynamicColorBlendState);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateDynamicDepthStencilState(VkDevice device, const VkDynamicDepthStencilStateCreateInfo* pCreateInfo, VkDynamicDepthStencilState* pState) {
+ return GetVtbl(device).CreateDynamicDepthStencilState(device, pCreateInfo, pState);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyDynamicDepthStencilState(VkDevice device, VkDynamicDepthStencilState dynamicDepthStencilState) {
+ return GetVtbl(device).DestroyDynamicDepthStencilState(device, dynamicDepthStencilState);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, VkFramebuffer* pFramebuffer) {
+ return GetVtbl(device).CreateFramebuffer(device, pCreateInfo, pFramebuffer);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer) {
+ return GetVtbl(device).DestroyFramebuffer(device, framebuffer);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, VkRenderPass* pRenderPass) {
+ return GetVtbl(device).CreateRenderPass(device, pCreateInfo, pRenderPass);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyRenderPass(VkDevice device, VkRenderPass renderPass) {
+ return GetVtbl(device).DestroyRenderPass(device, renderPass);
+}
+
+__attribute__((visibility("default")))
+VkResult vkGetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass, VkExtent2D* pGranularity) {
+ return GetVtbl(device).GetRenderAreaGranularity(device, renderPass, pGranularity);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateCommandPool(VkDevice device, const VkCmdPoolCreateInfo* pCreateInfo, VkCmdPool* pCmdPool) {
+ return GetVtbl(device).CreateCommandPool(device, pCreateInfo, pCmdPool);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyCommandPool(VkDevice device, VkCmdPool cmdPool) {
+ return GetVtbl(device).DestroyCommandPool(device, cmdPool);
+}
+
+__attribute__((visibility("default")))
+VkResult vkResetCommandPool(VkDevice device, VkCmdPool cmdPool, VkCmdPoolResetFlags flags) {
+ return GetVtbl(device).ResetCommandPool(device, cmdPool, flags);
+}
+
+__attribute__((visibility("default")))
+VkResult vkCreateCommandBuffer(VkDevice device, const VkCmdBufferCreateInfo* pCreateInfo, VkCmdBuffer* pCmdBuffer) {
+ return GetVtbl(device).CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
+}
+
+__attribute__((visibility("default")))
+VkResult vkDestroyCommandBuffer(VkDevice device, VkCmdBuffer commandBuffer) {
+ return GetVtbl(device).DestroyCommandBuffer(device, commandBuffer);
+}
+
+__attribute__((visibility("default")))
+VkResult vkBeginCommandBuffer(VkCmdBuffer cmdBuffer, const VkCmdBufferBeginInfo* pBeginInfo) {
+ return GetVtbl(cmdBuffer).BeginCommandBuffer(cmdBuffer, pBeginInfo);
+}
+
+__attribute__((visibility("default")))
+VkResult vkEndCommandBuffer(VkCmdBuffer cmdBuffer) {
+ return GetVtbl(cmdBuffer).EndCommandBuffer(cmdBuffer);
+}
+
+__attribute__((visibility("default")))
+VkResult vkResetCommandBuffer(VkCmdBuffer cmdBuffer, VkCmdBufferResetFlags flags) {
+ return GetVtbl(cmdBuffer).ResetCommandBuffer(cmdBuffer, flags);
+}
+
+__attribute__((visibility("default")))
+void vkCmdBindPipeline(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline) {
+ GetVtbl(cmdBuffer).CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
+}
+
+__attribute__((visibility("default")))
+void vkCmdBindDynamicViewportState(VkCmdBuffer cmdBuffer, VkDynamicViewportState dynamicViewportState) {
+ GetVtbl(cmdBuffer).CmdBindDynamicViewportState(cmdBuffer, dynamicViewportState);
+}
+
+__attribute__((visibility("default")))
+void vkCmdBindDynamicRasterState(VkCmdBuffer cmdBuffer, VkDynamicRasterState dynamicRasterState) {
+ GetVtbl(cmdBuffer).CmdBindDynamicRasterState(cmdBuffer, dynamicRasterState);
+}
+
+__attribute__((visibility("default")))
+void vkCmdBindDynamicColorBlendState(VkCmdBuffer cmdBuffer, VkDynamicColorBlendState dynamicColorBlendState) {
+ GetVtbl(cmdBuffer).CmdBindDynamicColorBlendState(cmdBuffer, dynamicColorBlendState);
+}
+
+__attribute__((visibility("default")))
+void vkCmdBindDynamicDepthStencilState(VkCmdBuffer cmdBuffer, VkDynamicDepthStencilState dynamicDepthStencilState) {
+ GetVtbl(cmdBuffer).CmdBindDynamicDepthStencilState(cmdBuffer, dynamicDepthStencilState);
+}
+
+__attribute__((visibility("default")))
+void vkCmdBindDescriptorSets(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t setCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets) {
+ GetVtbl(cmdBuffer).CmdBindDescriptorSets(cmdBuffer, pipelineBindPoint, layout, firstSet, setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
+}
+
+__attribute__((visibility("default")))
+void vkCmdBindIndexBuffer(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType) {
+ GetVtbl(cmdBuffer).CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
+}
+
+__attribute__((visibility("default")))
+void vkCmdBindVertexBuffers(VkCmdBuffer cmdBuffer, uint32_t startBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets) {
+ GetVtbl(cmdBuffer).CmdBindVertexBuffers(cmdBuffer, startBinding, bindingCount, pBuffers, pOffsets);
+}
+
+__attribute__((visibility("default")))
+void vkCmdDraw(VkCmdBuffer cmdBuffer, uint32_t firstVertex, uint32_t vertexCount, uint32_t firstInstance, uint32_t instanceCount) {
+ GetVtbl(cmdBuffer).CmdDraw(cmdBuffer, firstVertex, vertexCount, firstInstance, instanceCount);
+}
+
+__attribute__((visibility("default")))
+void vkCmdDrawIndexed(VkCmdBuffer cmdBuffer, uint32_t firstIndex, uint32_t indexCount, int32_t vertexOffset, uint32_t firstInstance, uint32_t instanceCount) {
+ GetVtbl(cmdBuffer).CmdDrawIndexed(cmdBuffer, firstIndex, indexCount, vertexOffset, firstInstance, instanceCount);
+}
+
+__attribute__((visibility("default")))
+void vkCmdDrawIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride) {
+ GetVtbl(cmdBuffer).CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
+}
+
+__attribute__((visibility("default")))
+void vkCmdDrawIndexedIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride) {
+ GetVtbl(cmdBuffer).CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
+}
+
+__attribute__((visibility("default")))
+void vkCmdDispatch(VkCmdBuffer cmdBuffer, uint32_t x, uint32_t y, uint32_t z) {
+ GetVtbl(cmdBuffer).CmdDispatch(cmdBuffer, x, y, z);
+}
+
+__attribute__((visibility("default")))
+void vkCmdDispatchIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset) {
+ GetVtbl(cmdBuffer).CmdDispatchIndirect(cmdBuffer, buffer, offset);
+}
+
+__attribute__((visibility("default")))
+void vkCmdCopyBuffer(VkCmdBuffer cmdBuffer, VkBuffer srcBuffer, VkBuffer destBuffer, uint32_t regionCount, const VkBufferCopy* pRegions) {
+ GetVtbl(cmdBuffer).CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
+}
+
+__attribute__((visibility("default")))
+void vkCmdCopyImage(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageCopy* pRegions) {
+ GetVtbl(cmdBuffer).CmdCopyImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
+}
+
+__attribute__((visibility("default")))
+void vkCmdBlitImage(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageBlit* pRegions, VkTexFilter filter) {
+ GetVtbl(cmdBuffer).CmdBlitImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions, filter);
+}
+
+__attribute__((visibility("default")))
+void vkCmdCopyBufferToImage(VkCmdBuffer cmdBuffer, VkBuffer srcBuffer, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions) {
+ GetVtbl(cmdBuffer).CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, destImageLayout, regionCount, pRegions);
+}
+
+__attribute__((visibility("default")))
+void vkCmdCopyImageToBuffer(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer destBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions) {
+ GetVtbl(cmdBuffer).CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
+}
+
+__attribute__((visibility("default")))
+void vkCmdUpdateBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize dataSize, const uint32_t* pData) {
+ GetVtbl(cmdBuffer).CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
+}
+
+__attribute__((visibility("default")))
+void vkCmdFillBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize fillSize, uint32_t data) {
+ GetVtbl(cmdBuffer).CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
+}
+
+__attribute__((visibility("default")))
+void vkCmdClearColorImage(VkCmdBuffer cmdBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges) {
+ GetVtbl(cmdBuffer).CmdClearColorImage(cmdBuffer, image, imageLayout, pColor, rangeCount, pRanges);
+}
+
+__attribute__((visibility("default")))
+void vkCmdClearDepthStencilImage(VkCmdBuffer cmdBuffer, VkImage image, VkImageLayout imageLayout, float depth, uint32_t stencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges) {
+ GetVtbl(cmdBuffer).CmdClearDepthStencilImage(cmdBuffer, image, imageLayout, depth, stencil, rangeCount, pRanges);
+}
+
+__attribute__((visibility("default")))
+void vkCmdClearColorAttachment(VkCmdBuffer cmdBuffer, uint32_t colorAttachment, VkImageLayout imageLayout, const VkClearColorValue* pColor, uint32_t rectCount, const VkRect3D* pRects) {
+ GetVtbl(cmdBuffer).CmdClearColorAttachment(cmdBuffer, colorAttachment, imageLayout, pColor, rectCount, pRects);
+}
+
+__attribute__((visibility("default")))
+void vkCmdClearDepthStencilAttachment(VkCmdBuffer cmdBuffer, VkImageAspectFlags imageAspectMask, VkImageLayout imageLayout, float depth, uint32_t stencil, uint32_t rectCount, const VkRect3D* pRects) {
+ GetVtbl(cmdBuffer).CmdClearDepthStencilAttachment(cmdBuffer, imageAspectMask, imageLayout, depth, stencil, rectCount, pRects);
+}
+
+__attribute__((visibility("default")))
+void vkCmdResolveImage(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageResolve* pRegions) {
+ GetVtbl(cmdBuffer).CmdResolveImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
+}
+
+__attribute__((visibility("default")))
+void vkCmdSetEvent(VkCmdBuffer cmdBuffer, VkEvent event, VkPipelineStageFlags stageMask) {
+ GetVtbl(cmdBuffer).CmdSetEvent(cmdBuffer, event, stageMask);
+}
+
+__attribute__((visibility("default")))
+void vkCmdResetEvent(VkCmdBuffer cmdBuffer, VkEvent event, VkPipelineStageFlags stageMask) {
+ GetVtbl(cmdBuffer).CmdResetEvent(cmdBuffer, event, stageMask);
+}
+
+__attribute__((visibility("default")))
+void vkCmdWaitEvents(VkCmdBuffer cmdBuffer, uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags destStageMask, uint32_t memBarrierCount, const void* const* ppMemBarriers) {
+ GetVtbl(cmdBuffer).CmdWaitEvents(cmdBuffer, eventCount, pEvents, srcStageMask, destStageMask, memBarrierCount, ppMemBarriers);
+}
+
+__attribute__((visibility("default")))
+void vkCmdPipelineBarrier(VkCmdBuffer cmdBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags destStageMask, VkBool32 byRegion, uint32_t memBarrierCount, const void* const* ppMemBarriers) {
+ GetVtbl(cmdBuffer).CmdPipelineBarrier(cmdBuffer, srcStageMask, destStageMask, byRegion, memBarrierCount, ppMemBarriers);
+}
+
+__attribute__((visibility("default")))
+void vkCmdBeginQuery(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t slot, VkQueryControlFlags flags) {
+ GetVtbl(cmdBuffer).CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
+}
+
+__attribute__((visibility("default")))
+void vkCmdEndQuery(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t slot) {
+ GetVtbl(cmdBuffer).CmdEndQuery(cmdBuffer, queryPool, slot);
+}
+
+__attribute__((visibility("default")))
+void vkCmdResetQueryPool(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t startQuery, uint32_t queryCount) {
+ GetVtbl(cmdBuffer).CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
+}
+
+__attribute__((visibility("default")))
+void vkCmdWriteTimestamp(VkCmdBuffer cmdBuffer, VkTimestampType timestampType, VkBuffer destBuffer, VkDeviceSize destOffset) {
+ GetVtbl(cmdBuffer).CmdWriteTimestamp(cmdBuffer, timestampType, destBuffer, destOffset);
+}
+
+__attribute__((visibility("default")))
+void vkCmdCopyQueryPoolResults(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t startQuery, uint32_t queryCount, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize destStride, VkQueryResultFlags flags) {
+ GetVtbl(cmdBuffer).CmdCopyQueryPoolResults(cmdBuffer, queryPool, startQuery, queryCount, destBuffer, destOffset, destStride, flags);
+}
+
+__attribute__((visibility("default")))
+void vkCmdPushConstants(VkCmdBuffer cmdBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t start, uint32_t length, const void* values) {
+ GetVtbl(cmdBuffer).CmdPushConstants(cmdBuffer, layout, stageFlags, start, length, values);
+}
+
+__attribute__((visibility("default")))
+void vkCmdBeginRenderPass(VkCmdBuffer cmdBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, VkRenderPassContents contents) {
+ GetVtbl(cmdBuffer).CmdBeginRenderPass(cmdBuffer, pRenderPassBegin, contents);
+}
+
+__attribute__((visibility("default")))
+void vkCmdNextSubpass(VkCmdBuffer cmdBuffer, VkRenderPassContents contents) {
+ GetVtbl(cmdBuffer).CmdNextSubpass(cmdBuffer, contents);
+}
+
+__attribute__((visibility("default")))
+void vkCmdEndRenderPass(VkCmdBuffer cmdBuffer) {
+ GetVtbl(cmdBuffer).CmdEndRenderPass(cmdBuffer);
+}
+
+__attribute__((visibility("default")))
+void vkCmdExecuteCommands(VkCmdBuffer cmdBuffer, uint32_t cmdBuffersCount, const VkCmdBuffer* pCmdBuffers) {
+ GetVtbl(cmdBuffer).CmdExecuteCommands(cmdBuffer, cmdBuffersCount, pCmdBuffers);
+}
diff --git a/vulkan/libvulkan/entry.cpp.tmpl b/vulkan/libvulkan/entry.cpp.tmpl
new file mode 100644
index 0000000..249f8fd
--- /dev/null
+++ b/vulkan/libvulkan/entry.cpp.tmpl
@@ -0,0 +1,145 @@
+{{Include "../api/templates/vulkan_common.tmpl"}}
+{{Macro "DefineGlobals" $}}
+{{$ | Macro "entry.cpp" | Reflow 4 | Write "entry.cpp"}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+ Entry point
+-------------------------------------------------------------------------------
+*/}}
+{{define "entry.cpp"}}
+/*
+ * Copyright 2015 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.
+ */
+¶
+// This file is generated. Do not edit manually!
+// To regenerate: $ apic template ../api/vulkan.api entry.cpp.tmpl
+// Requires apic from https://android.googlesource.com/platform/tools/gpu/.
+¶
+#include "loader.h"
+using namespace vulkan;
+¶
+// clang-format off
+¶
+namespace {
+ inline const InstanceVtbl& GetVtbl(VkInstance instance) {
+ return **reinterpret_cast<InstanceVtbl**>(instance);
+ }
+ inline const InstanceVtbl& GetVtbl(VkPhysicalDevice physicalDevice) {
+ return **reinterpret_cast<InstanceVtbl**>(physicalDevice);
+ }
+ inline const DeviceVtbl& GetVtbl(VkDevice device) {
+ return **reinterpret_cast<DeviceVtbl**>(device);
+ }
+ inline const DeviceVtbl& GetVtbl(VkQueue queue) {
+ return **reinterpret_cast<DeviceVtbl**>(queue);
+ }
+ inline const DeviceVtbl& GetVtbl(VkCmdBuffer cmdBuffer) {
+ return **reinterpret_cast<DeviceVtbl**>(cmdBuffer);
+ }
+} // namespace
+¶
+ {{range $f := AllCommands $}}
+ {{if not (GetAnnotation $f "pfn")}}
+ __attribute__((visibility("default")))
+ {{if eq (Macro "IsSpecialEntry" $f.Name) "true"}}
+ {{Macro "EmitSpecialEntry" $f}}
+ {{else}}
+ {{Macro "EmitEntry" $f}}
+ {{end}}
+ {{end}}
+ {{end}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+ Decides whether an entrypoint needs special-case handling. Emits the string
+ "true" if so, nothing otherwise.
+-------------------------------------------------------------------------------
+*/}}
+{{define "IsSpecialEntry"}}
+ {{/* TODO: figure out how to do this in a cleaner or at least multi-line way */}}
+ {{if or (eq $ "vkGetInstanceProcAddr") (or (eq $ "vkGetDeviceProcAddr") (or (eq $ "vkGetDeviceQueue") (eq $ "vkDestroyDevice")))}}
+ true
+ {{end}}
+{{end}}
+
+{{/*
+-------------------------------------------------------------------------------
+ Emits the entrypoint definition for the specified command, which always
+ dispatches statically because the function requires special-case handling.
+-------------------------------------------------------------------------------
+*/}}
+{{define "EmitSpecialEntry"}}
+ {{AssertType $ "Function"}}
+
+ {{Node "Type" $.Return}} {{Macro "FunctionName" $}}({{Macro "Parameters" $}}) {
+ {{if not (IsVoid $.Return.Type)}}return §{{end}}
+ vulkan::{{TrimPrefix "vk" $.Name}}({{Macro "Arguments" $}});
+ }
+ ¶
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+ Emits the entrypoint definition for the specified command. If the first
+ parameter is a handle to dispatchable object, it dispatches the call through
+ the object's function table. Otherwise, it dispatches statically.
+-------------------------------------------------------------------------------
+*/}}
+{{define "EmitEntry"}}
+ {{AssertType $ "Function"}}
+
+ {{Node "Type" $.Return}} {{Macro "FunctionName" $}}({{Macro "Parameters" $}}) {
+ {{if not (IsVoid $.Return.Type)}}return §{{end}}
+ {{Macro "Dispatch" $}}{{TrimPrefix "vk" $.Name}}({{Macro "Arguments" $}});
+ }
+ ¶
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+ Emit the dispatch lookup for a function based on its first parameter.
+-------------------------------------------------------------------------------
+*/}}
+{{define "Dispatch#VkInstance" }}GetVtbl({{$.Node.Name}}).{{end}}
+{{define "Dispatch#VkPhysicalDevice"}}GetVtbl({{$.Node.Name}}).{{end}}
+{{define "Dispatch#VkDevice" }}GetVtbl({{$.Node.Name}}).{{end}}
+{{define "Dispatch#VkQueue" }}GetVtbl({{$.Node.Name}}).{{end}}
+{{define "Dispatch#VkCmdBuffer" }}GetVtbl({{$.Node.Name}}).{{end}}
+{{define "Dispatch_Default" }}vulkan::{{end}}
+{{define "Dispatch"}}
+ {{AssertType $ "Function"}}
+
+ {{range $i, $p := $.CallParameters}}
+ {{if not $i}}{{Node "Dispatch" $p}}{{end}}
+ {{end}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+ Emits a comma-separated list of C parameter names for the given command.
+-------------------------------------------------------------------------------
+*/}}
+{{define "Arguments"}}
+ {{AssertType $ "Function"}}
+
+ {{ForEach $.CallParameters "ParameterName" | JoinWith ", "}}
+{{end}}
diff --git a/vulkan/libvulkan/get_proc_addr.cpp b/vulkan/libvulkan/get_proc_addr.cpp
new file mode 100644
index 0000000..5f05f0e
--- /dev/null
+++ b/vulkan/libvulkan/get_proc_addr.cpp
@@ -0,0 +1,1167 @@
+/*
+* Copyright 2015 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.
+*/
+
+// This file is generated. Do not edit manually!
+// To regenerate: $ apic template ../api/vulkan.api get_proc_addr.cpp.tmpl
+// Requires apic from https://android.googlesource.com/platform/tools/gpu/.
+
+#include <algorithm>
+#include <log/log.h>
+#include "loader.h"
+using namespace vulkan;
+
+#define UNLIKELY(expr) __builtin_expect((expr), 0)
+
+namespace {
+
+struct NameProcEntry {
+ const char* name;
+ PFN_vkVoidFunction proc;
+};
+
+struct NameOffsetEntry {
+ const char* name;
+ size_t offset;
+};
+
+template <typename TEntry, size_t N>
+const TEntry* FindProcEntry(const TEntry(&table)[N], const char* name) {
+ auto entry = std::lower_bound(
+ table, table + N, name,
+ [](const TEntry& e, const char* n) { return strcmp(e.name, n) < 0; });
+ if (entry != (table + N) && strcmp(entry->name, name) == 0)
+ return entry;
+ return nullptr;
+}
+
+const NameProcEntry kInstanceProcTbl[] = {
+ // clang-format off
+ {"vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(vkCreateDevice)},
+ {"vkDestroyInstance", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyInstance)},
+ {"vkEnumeratePhysicalDevices", reinterpret_cast<PFN_vkVoidFunction>(vkEnumeratePhysicalDevices)},
+ {"vkGetInstanceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(vkGetInstanceProcAddr)},
+ {"vkGetPhysicalDeviceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceExtensionProperties)},
+ {"vkGetPhysicalDeviceFeatures", reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceFeatures)},
+ {"vkGetPhysicalDeviceFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceFormatProperties)},
+ {"vkGetPhysicalDeviceImageFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceImageFormatProperties)},
+ {"vkGetPhysicalDeviceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceLayerProperties)},
+ {"vkGetPhysicalDeviceLimits", reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceLimits)},
+ {"vkGetPhysicalDeviceMemoryProperties", reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceMemoryProperties)},
+ {"vkGetPhysicalDeviceProperties", reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceProperties)},
+ {"vkGetPhysicalDeviceQueueCount", reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceQueueCount)},
+ {"vkGetPhysicalDeviceQueueProperties", reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceQueueProperties)},
+ {"vkGetPhysicalDeviceSparseImageFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceSparseImageFormatProperties)},
+ // clang-format on
+};
+
+const NameProcEntry kDeviceProcTbl[] = {
+ // clang-format off
+ {"vkAllocDescriptorSets", reinterpret_cast<PFN_vkVoidFunction>(vkAllocDescriptorSets)},
+ {"vkAllocMemory", reinterpret_cast<PFN_vkVoidFunction>(vkAllocMemory)},
+ {"vkBeginCommandBuffer", reinterpret_cast<PFN_vkVoidFunction>(vkBeginCommandBuffer)},
+ {"vkBindBufferMemory", reinterpret_cast<PFN_vkVoidFunction>(vkBindBufferMemory)},
+ {"vkBindImageMemory", reinterpret_cast<PFN_vkVoidFunction>(vkBindImageMemory)},
+ {"vkCmdBeginQuery", reinterpret_cast<PFN_vkVoidFunction>(vkCmdBeginQuery)},
+ {"vkCmdBeginRenderPass", reinterpret_cast<PFN_vkVoidFunction>(vkCmdBeginRenderPass)},
+ {"vkCmdBindDescriptorSets", reinterpret_cast<PFN_vkVoidFunction>(vkCmdBindDescriptorSets)},
+ {"vkCmdBindDynamicColorBlendState", reinterpret_cast<PFN_vkVoidFunction>(vkCmdBindDynamicColorBlendState)},
+ {"vkCmdBindDynamicDepthStencilState", reinterpret_cast<PFN_vkVoidFunction>(vkCmdBindDynamicDepthStencilState)},
+ {"vkCmdBindDynamicRasterState", reinterpret_cast<PFN_vkVoidFunction>(vkCmdBindDynamicRasterState)},
+ {"vkCmdBindDynamicViewportState", reinterpret_cast<PFN_vkVoidFunction>(vkCmdBindDynamicViewportState)},
+ {"vkCmdBindIndexBuffer", reinterpret_cast<PFN_vkVoidFunction>(vkCmdBindIndexBuffer)},
+ {"vkCmdBindPipeline", reinterpret_cast<PFN_vkVoidFunction>(vkCmdBindPipeline)},
+ {"vkCmdBindVertexBuffers", reinterpret_cast<PFN_vkVoidFunction>(vkCmdBindVertexBuffers)},
+ {"vkCmdBlitImage", reinterpret_cast<PFN_vkVoidFunction>(vkCmdBlitImage)},
+ {"vkCmdClearColorAttachment", reinterpret_cast<PFN_vkVoidFunction>(vkCmdClearColorAttachment)},
+ {"vkCmdClearColorImage", reinterpret_cast<PFN_vkVoidFunction>(vkCmdClearColorImage)},
+ {"vkCmdClearDepthStencilAttachment", reinterpret_cast<PFN_vkVoidFunction>(vkCmdClearDepthStencilAttachment)},
+ {"vkCmdClearDepthStencilImage", reinterpret_cast<PFN_vkVoidFunction>(vkCmdClearDepthStencilImage)},
+ {"vkCmdCopyBuffer", reinterpret_cast<PFN_vkVoidFunction>(vkCmdCopyBuffer)},
+ {"vkCmdCopyBufferToImage", reinterpret_cast<PFN_vkVoidFunction>(vkCmdCopyBufferToImage)},
+ {"vkCmdCopyImage", reinterpret_cast<PFN_vkVoidFunction>(vkCmdCopyImage)},
+ {"vkCmdCopyImageToBuffer", reinterpret_cast<PFN_vkVoidFunction>(vkCmdCopyImageToBuffer)},
+ {"vkCmdCopyQueryPoolResults", reinterpret_cast<PFN_vkVoidFunction>(vkCmdCopyQueryPoolResults)},
+ {"vkCmdDispatch", reinterpret_cast<PFN_vkVoidFunction>(vkCmdDispatch)},
+ {"vkCmdDispatchIndirect", reinterpret_cast<PFN_vkVoidFunction>(vkCmdDispatchIndirect)},
+ {"vkCmdDraw", reinterpret_cast<PFN_vkVoidFunction>(vkCmdDraw)},
+ {"vkCmdDrawIndexed", reinterpret_cast<PFN_vkVoidFunction>(vkCmdDrawIndexed)},
+ {"vkCmdDrawIndexedIndirect", reinterpret_cast<PFN_vkVoidFunction>(vkCmdDrawIndexedIndirect)},
+ {"vkCmdDrawIndirect", reinterpret_cast<PFN_vkVoidFunction>(vkCmdDrawIndirect)},
+ {"vkCmdEndQuery", reinterpret_cast<PFN_vkVoidFunction>(vkCmdEndQuery)},
+ {"vkCmdEndRenderPass", reinterpret_cast<PFN_vkVoidFunction>(vkCmdEndRenderPass)},
+ {"vkCmdExecuteCommands", reinterpret_cast<PFN_vkVoidFunction>(vkCmdExecuteCommands)},
+ {"vkCmdFillBuffer", reinterpret_cast<PFN_vkVoidFunction>(vkCmdFillBuffer)},
+ {"vkCmdNextSubpass", reinterpret_cast<PFN_vkVoidFunction>(vkCmdNextSubpass)},
+ {"vkCmdPipelineBarrier", reinterpret_cast<PFN_vkVoidFunction>(vkCmdPipelineBarrier)},
+ {"vkCmdPushConstants", reinterpret_cast<PFN_vkVoidFunction>(vkCmdPushConstants)},
+ {"vkCmdResetEvent", reinterpret_cast<PFN_vkVoidFunction>(vkCmdResetEvent)},
+ {"vkCmdResetQueryPool", reinterpret_cast<PFN_vkVoidFunction>(vkCmdResetQueryPool)},
+ {"vkCmdResolveImage", reinterpret_cast<PFN_vkVoidFunction>(vkCmdResolveImage)},
+ {"vkCmdSetEvent", reinterpret_cast<PFN_vkVoidFunction>(vkCmdSetEvent)},
+ {"vkCmdUpdateBuffer", reinterpret_cast<PFN_vkVoidFunction>(vkCmdUpdateBuffer)},
+ {"vkCmdWaitEvents", reinterpret_cast<PFN_vkVoidFunction>(vkCmdWaitEvents)},
+ {"vkCmdWriteTimestamp", reinterpret_cast<PFN_vkVoidFunction>(vkCmdWriteTimestamp)},
+ {"vkCreateAttachmentView", reinterpret_cast<PFN_vkVoidFunction>(vkCreateAttachmentView)},
+ {"vkCreateBuffer", reinterpret_cast<PFN_vkVoidFunction>(vkCreateBuffer)},
+ {"vkCreateBufferView", reinterpret_cast<PFN_vkVoidFunction>(vkCreateBufferView)},
+ {"vkCreateCommandBuffer", reinterpret_cast<PFN_vkVoidFunction>(vkCreateCommandBuffer)},
+ {"vkCreateCommandPool", reinterpret_cast<PFN_vkVoidFunction>(vkCreateCommandPool)},
+ {"vkCreateComputePipelines", reinterpret_cast<PFN_vkVoidFunction>(vkCreateComputePipelines)},
+ {"vkCreateDescriptorPool", reinterpret_cast<PFN_vkVoidFunction>(vkCreateDescriptorPool)},
+ {"vkCreateDescriptorSetLayout", reinterpret_cast<PFN_vkVoidFunction>(vkCreateDescriptorSetLayout)},
+ {"vkCreateDynamicColorBlendState", reinterpret_cast<PFN_vkVoidFunction>(vkCreateDynamicColorBlendState)},
+ {"vkCreateDynamicDepthStencilState", reinterpret_cast<PFN_vkVoidFunction>(vkCreateDynamicDepthStencilState)},
+ {"vkCreateDynamicRasterState", reinterpret_cast<PFN_vkVoidFunction>(vkCreateDynamicRasterState)},
+ {"vkCreateDynamicViewportState", reinterpret_cast<PFN_vkVoidFunction>(vkCreateDynamicViewportState)},
+ {"vkCreateEvent", reinterpret_cast<PFN_vkVoidFunction>(vkCreateEvent)},
+ {"vkCreateFence", reinterpret_cast<PFN_vkVoidFunction>(vkCreateFence)},
+ {"vkCreateFramebuffer", reinterpret_cast<PFN_vkVoidFunction>(vkCreateFramebuffer)},
+ {"vkCreateGraphicsPipelines", reinterpret_cast<PFN_vkVoidFunction>(vkCreateGraphicsPipelines)},
+ {"vkCreateImage", reinterpret_cast<PFN_vkVoidFunction>(vkCreateImage)},
+ {"vkCreateImageView", reinterpret_cast<PFN_vkVoidFunction>(vkCreateImageView)},
+ {"vkCreatePipelineCache", reinterpret_cast<PFN_vkVoidFunction>(vkCreatePipelineCache)},
+ {"vkCreatePipelineLayout", reinterpret_cast<PFN_vkVoidFunction>(vkCreatePipelineLayout)},
+ {"vkCreateQueryPool", reinterpret_cast<PFN_vkVoidFunction>(vkCreateQueryPool)},
+ {"vkCreateRenderPass", reinterpret_cast<PFN_vkVoidFunction>(vkCreateRenderPass)},
+ {"vkCreateSampler", reinterpret_cast<PFN_vkVoidFunction>(vkCreateSampler)},
+ {"vkCreateSemaphore", reinterpret_cast<PFN_vkVoidFunction>(vkCreateSemaphore)},
+ {"vkCreateShader", reinterpret_cast<PFN_vkVoidFunction>(vkCreateShader)},
+ {"vkCreateShaderModule", reinterpret_cast<PFN_vkVoidFunction>(vkCreateShaderModule)},
+ {"vkDestroyAttachmentView", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyAttachmentView)},
+ {"vkDestroyBuffer", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyBuffer)},
+ {"vkDestroyBufferView", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyBufferView)},
+ {"vkDestroyCommandBuffer", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyCommandBuffer)},
+ {"vkDestroyCommandPool", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyCommandPool)},
+ {"vkDestroyDescriptorPool", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyDescriptorPool)},
+ {"vkDestroyDescriptorSetLayout", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyDescriptorSetLayout)},
+ {"vkDestroyDevice", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyDevice)},
+ {"vkDestroyDynamicColorBlendState", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyDynamicColorBlendState)},
+ {"vkDestroyDynamicDepthStencilState", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyDynamicDepthStencilState)},
+ {"vkDestroyDynamicRasterState", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyDynamicRasterState)},
+ {"vkDestroyDynamicViewportState", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyDynamicViewportState)},
+ {"vkDestroyEvent", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyEvent)},
+ {"vkDestroyFence", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyFence)},
+ {"vkDestroyFramebuffer", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyFramebuffer)},
+ {"vkDestroyImage", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyImage)},
+ {"vkDestroyImageView", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyImageView)},
+ {"vkDestroyPipeline", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyPipeline)},
+ {"vkDestroyPipelineCache", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyPipelineCache)},
+ {"vkDestroyPipelineLayout", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyPipelineLayout)},
+ {"vkDestroyQueryPool", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyQueryPool)},
+ {"vkDestroyRenderPass", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyRenderPass)},
+ {"vkDestroySampler", reinterpret_cast<PFN_vkVoidFunction>(vkDestroySampler)},
+ {"vkDestroySemaphore", reinterpret_cast<PFN_vkVoidFunction>(vkDestroySemaphore)},
+ {"vkDestroyShader", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyShader)},
+ {"vkDestroyShaderModule", reinterpret_cast<PFN_vkVoidFunction>(vkDestroyShaderModule)},
+ {"vkDeviceWaitIdle", reinterpret_cast<PFN_vkVoidFunction>(vkDeviceWaitIdle)},
+ {"vkEndCommandBuffer", reinterpret_cast<PFN_vkVoidFunction>(vkEndCommandBuffer)},
+ {"vkFlushMappedMemoryRanges", reinterpret_cast<PFN_vkVoidFunction>(vkFlushMappedMemoryRanges)},
+ {"vkFreeDescriptorSets", reinterpret_cast<PFN_vkVoidFunction>(vkFreeDescriptorSets)},
+ {"vkFreeMemory", reinterpret_cast<PFN_vkVoidFunction>(vkFreeMemory)},
+ {"vkGetBufferMemoryRequirements", reinterpret_cast<PFN_vkVoidFunction>(vkGetBufferMemoryRequirements)},
+ {"vkGetDeviceMemoryCommitment", reinterpret_cast<PFN_vkVoidFunction>(vkGetDeviceMemoryCommitment)},
+ {"vkGetDeviceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(vkGetDeviceProcAddr)},
+ {"vkGetDeviceQueue", reinterpret_cast<PFN_vkVoidFunction>(vkGetDeviceQueue)},
+ {"vkGetEventStatus", reinterpret_cast<PFN_vkVoidFunction>(vkGetEventStatus)},
+ {"vkGetFenceStatus", reinterpret_cast<PFN_vkVoidFunction>(vkGetFenceStatus)},
+ {"vkGetImageMemoryRequirements", reinterpret_cast<PFN_vkVoidFunction>(vkGetImageMemoryRequirements)},
+ {"vkGetImageSparseMemoryRequirements", reinterpret_cast<PFN_vkVoidFunction>(vkGetImageSparseMemoryRequirements)},
+ {"vkGetImageSubresourceLayout", reinterpret_cast<PFN_vkVoidFunction>(vkGetImageSubresourceLayout)},
+ {"vkGetPipelineCacheData", reinterpret_cast<PFN_vkVoidFunction>(vkGetPipelineCacheData)},
+ {"vkGetPipelineCacheSize", reinterpret_cast<PFN_vkVoidFunction>(vkGetPipelineCacheSize)},
+ {"vkGetQueryPoolResults", reinterpret_cast<PFN_vkVoidFunction>(vkGetQueryPoolResults)},
+ {"vkGetRenderAreaGranularity", reinterpret_cast<PFN_vkVoidFunction>(vkGetRenderAreaGranularity)},
+ {"vkInvalidateMappedMemoryRanges", reinterpret_cast<PFN_vkVoidFunction>(vkInvalidateMappedMemoryRanges)},
+ {"vkMapMemory", reinterpret_cast<PFN_vkVoidFunction>(vkMapMemory)},
+ {"vkMergePipelineCaches", reinterpret_cast<PFN_vkVoidFunction>(vkMergePipelineCaches)},
+ {"vkQueueBindSparseBufferMemory", reinterpret_cast<PFN_vkVoidFunction>(vkQueueBindSparseBufferMemory)},
+ {"vkQueueBindSparseImageMemory", reinterpret_cast<PFN_vkVoidFunction>(vkQueueBindSparseImageMemory)},
+ {"vkQueueBindSparseImageOpaqueMemory", reinterpret_cast<PFN_vkVoidFunction>(vkQueueBindSparseImageOpaqueMemory)},
+ {"vkQueueSignalSemaphore", reinterpret_cast<PFN_vkVoidFunction>(vkQueueSignalSemaphore)},
+ {"vkQueueSubmit", reinterpret_cast<PFN_vkVoidFunction>(vkQueueSubmit)},
+ {"vkQueueWaitIdle", reinterpret_cast<PFN_vkVoidFunction>(vkQueueWaitIdle)},
+ {"vkQueueWaitSemaphore", reinterpret_cast<PFN_vkVoidFunction>(vkQueueWaitSemaphore)},
+ {"vkResetCommandBuffer", reinterpret_cast<PFN_vkVoidFunction>(vkResetCommandBuffer)},
+ {"vkResetCommandPool", reinterpret_cast<PFN_vkVoidFunction>(vkResetCommandPool)},
+ {"vkResetDescriptorPool", reinterpret_cast<PFN_vkVoidFunction>(vkResetDescriptorPool)},
+ {"vkResetEvent", reinterpret_cast<PFN_vkVoidFunction>(vkResetEvent)},
+ {"vkResetFences", reinterpret_cast<PFN_vkVoidFunction>(vkResetFences)},
+ {"vkSetEvent", reinterpret_cast<PFN_vkVoidFunction>(vkSetEvent)},
+ {"vkUnmapMemory", reinterpret_cast<PFN_vkVoidFunction>(vkUnmapMemory)},
+ {"vkUpdateDescriptorSets", reinterpret_cast<PFN_vkVoidFunction>(vkUpdateDescriptorSets)},
+ {"vkWaitForFences", reinterpret_cast<PFN_vkVoidFunction>(vkWaitForFences)},
+ // clang-format on
+};
+
+const NameOffsetEntry kInstanceOffsetTbl[] = {
+ // clang-format off
+ {"vkCreateDevice", offsetof(InstanceVtbl, CreateDevice)},
+ {"vkDestroyInstance", offsetof(InstanceVtbl, DestroyInstance)},
+ {"vkEnumeratePhysicalDevices", offsetof(InstanceVtbl, EnumeratePhysicalDevices)},
+ {"vkGetInstanceProcAddr", offsetof(InstanceVtbl, GetInstanceProcAddr)},
+ {"vkGetPhysicalDeviceExtensionProperties", offsetof(InstanceVtbl, GetPhysicalDeviceExtensionProperties)},
+ {"vkGetPhysicalDeviceFeatures", offsetof(InstanceVtbl, GetPhysicalDeviceFeatures)},
+ {"vkGetPhysicalDeviceFormatProperties", offsetof(InstanceVtbl, GetPhysicalDeviceFormatProperties)},
+ {"vkGetPhysicalDeviceImageFormatProperties", offsetof(InstanceVtbl, GetPhysicalDeviceImageFormatProperties)},
+ {"vkGetPhysicalDeviceLayerProperties", offsetof(InstanceVtbl, GetPhysicalDeviceLayerProperties)},
+ {"vkGetPhysicalDeviceLimits", offsetof(InstanceVtbl, GetPhysicalDeviceLimits)},
+ {"vkGetPhysicalDeviceMemoryProperties", offsetof(InstanceVtbl, GetPhysicalDeviceMemoryProperties)},
+ {"vkGetPhysicalDeviceProperties", offsetof(InstanceVtbl, GetPhysicalDeviceProperties)},
+ {"vkGetPhysicalDeviceQueueCount", offsetof(InstanceVtbl, GetPhysicalDeviceQueueCount)},
+ {"vkGetPhysicalDeviceQueueProperties", offsetof(InstanceVtbl, GetPhysicalDeviceQueueProperties)},
+ {"vkGetPhysicalDeviceSparseImageFormatProperties", offsetof(InstanceVtbl, GetPhysicalDeviceSparseImageFormatProperties)},
+ // clang-format on
+};
+
+const NameOffsetEntry kDeviceOffsetTbl[] = {
+ // clang-format off
+ {"vkAllocDescriptorSets", offsetof(DeviceVtbl, AllocDescriptorSets)},
+ {"vkAllocMemory", offsetof(DeviceVtbl, AllocMemory)},
+ {"vkBeginCommandBuffer", offsetof(DeviceVtbl, BeginCommandBuffer)},
+ {"vkBindBufferMemory", offsetof(DeviceVtbl, BindBufferMemory)},
+ {"vkBindImageMemory", offsetof(DeviceVtbl, BindImageMemory)},
+ {"vkCmdBeginQuery", offsetof(DeviceVtbl, CmdBeginQuery)},
+ {"vkCmdBeginRenderPass", offsetof(DeviceVtbl, CmdBeginRenderPass)},
+ {"vkCmdBindDescriptorSets", offsetof(DeviceVtbl, CmdBindDescriptorSets)},
+ {"vkCmdBindDynamicColorBlendState", offsetof(DeviceVtbl, CmdBindDynamicColorBlendState)},
+ {"vkCmdBindDynamicDepthStencilState", offsetof(DeviceVtbl, CmdBindDynamicDepthStencilState)},
+ {"vkCmdBindDynamicRasterState", offsetof(DeviceVtbl, CmdBindDynamicRasterState)},
+ {"vkCmdBindDynamicViewportState", offsetof(DeviceVtbl, CmdBindDynamicViewportState)},
+ {"vkCmdBindIndexBuffer", offsetof(DeviceVtbl, CmdBindIndexBuffer)},
+ {"vkCmdBindPipeline", offsetof(DeviceVtbl, CmdBindPipeline)},
+ {"vkCmdBindVertexBuffers", offsetof(DeviceVtbl, CmdBindVertexBuffers)},
+ {"vkCmdBlitImage", offsetof(DeviceVtbl, CmdBlitImage)},
+ {"vkCmdClearColorAttachment", offsetof(DeviceVtbl, CmdClearColorAttachment)},
+ {"vkCmdClearColorImage", offsetof(DeviceVtbl, CmdClearColorImage)},
+ {"vkCmdClearDepthStencilAttachment", offsetof(DeviceVtbl, CmdClearDepthStencilAttachment)},
+ {"vkCmdClearDepthStencilImage", offsetof(DeviceVtbl, CmdClearDepthStencilImage)},
+ {"vkCmdCopyBuffer", offsetof(DeviceVtbl, CmdCopyBuffer)},
+ {"vkCmdCopyBufferToImage", offsetof(DeviceVtbl, CmdCopyBufferToImage)},
+ {"vkCmdCopyImage", offsetof(DeviceVtbl, CmdCopyImage)},
+ {"vkCmdCopyImageToBuffer", offsetof(DeviceVtbl, CmdCopyImageToBuffer)},
+ {"vkCmdCopyQueryPoolResults", offsetof(DeviceVtbl, CmdCopyQueryPoolResults)},
+ {"vkCmdDispatch", offsetof(DeviceVtbl, CmdDispatch)},
+ {"vkCmdDispatchIndirect", offsetof(DeviceVtbl, CmdDispatchIndirect)},
+ {"vkCmdDraw", offsetof(DeviceVtbl, CmdDraw)},
+ {"vkCmdDrawIndexed", offsetof(DeviceVtbl, CmdDrawIndexed)},
+ {"vkCmdDrawIndexedIndirect", offsetof(DeviceVtbl, CmdDrawIndexedIndirect)},
+ {"vkCmdDrawIndirect", offsetof(DeviceVtbl, CmdDrawIndirect)},
+ {"vkCmdEndQuery", offsetof(DeviceVtbl, CmdEndQuery)},
+ {"vkCmdEndRenderPass", offsetof(DeviceVtbl, CmdEndRenderPass)},
+ {"vkCmdExecuteCommands", offsetof(DeviceVtbl, CmdExecuteCommands)},
+ {"vkCmdFillBuffer", offsetof(DeviceVtbl, CmdFillBuffer)},
+ {"vkCmdNextSubpass", offsetof(DeviceVtbl, CmdNextSubpass)},
+ {"vkCmdPipelineBarrier", offsetof(DeviceVtbl, CmdPipelineBarrier)},
+ {"vkCmdPushConstants", offsetof(DeviceVtbl, CmdPushConstants)},
+ {"vkCmdResetEvent", offsetof(DeviceVtbl, CmdResetEvent)},
+ {"vkCmdResetQueryPool", offsetof(DeviceVtbl, CmdResetQueryPool)},
+ {"vkCmdResolveImage", offsetof(DeviceVtbl, CmdResolveImage)},
+ {"vkCmdSetEvent", offsetof(DeviceVtbl, CmdSetEvent)},
+ {"vkCmdUpdateBuffer", offsetof(DeviceVtbl, CmdUpdateBuffer)},
+ {"vkCmdWaitEvents", offsetof(DeviceVtbl, CmdWaitEvents)},
+ {"vkCmdWriteTimestamp", offsetof(DeviceVtbl, CmdWriteTimestamp)},
+ {"vkCreateAttachmentView", offsetof(DeviceVtbl, CreateAttachmentView)},
+ {"vkCreateBuffer", offsetof(DeviceVtbl, CreateBuffer)},
+ {"vkCreateBufferView", offsetof(DeviceVtbl, CreateBufferView)},
+ {"vkCreateCommandBuffer", offsetof(DeviceVtbl, CreateCommandBuffer)},
+ {"vkCreateCommandPool", offsetof(DeviceVtbl, CreateCommandPool)},
+ {"vkCreateComputePipelines", offsetof(DeviceVtbl, CreateComputePipelines)},
+ {"vkCreateDescriptorPool", offsetof(DeviceVtbl, CreateDescriptorPool)},
+ {"vkCreateDescriptorSetLayout", offsetof(DeviceVtbl, CreateDescriptorSetLayout)},
+ {"vkCreateDynamicColorBlendState", offsetof(DeviceVtbl, CreateDynamicColorBlendState)},
+ {"vkCreateDynamicDepthStencilState", offsetof(DeviceVtbl, CreateDynamicDepthStencilState)},
+ {"vkCreateDynamicRasterState", offsetof(DeviceVtbl, CreateDynamicRasterState)},
+ {"vkCreateDynamicViewportState", offsetof(DeviceVtbl, CreateDynamicViewportState)},
+ {"vkCreateEvent", offsetof(DeviceVtbl, CreateEvent)},
+ {"vkCreateFence", offsetof(DeviceVtbl, CreateFence)},
+ {"vkCreateFramebuffer", offsetof(DeviceVtbl, CreateFramebuffer)},
+ {"vkCreateGraphicsPipelines", offsetof(DeviceVtbl, CreateGraphicsPipelines)},
+ {"vkCreateImage", offsetof(DeviceVtbl, CreateImage)},
+ {"vkCreateImageView", offsetof(DeviceVtbl, CreateImageView)},
+ {"vkCreatePipelineCache", offsetof(DeviceVtbl, CreatePipelineCache)},
+ {"vkCreatePipelineLayout", offsetof(DeviceVtbl, CreatePipelineLayout)},
+ {"vkCreateQueryPool", offsetof(DeviceVtbl, CreateQueryPool)},
+ {"vkCreateRenderPass", offsetof(DeviceVtbl, CreateRenderPass)},
+ {"vkCreateSampler", offsetof(DeviceVtbl, CreateSampler)},
+ {"vkCreateSemaphore", offsetof(DeviceVtbl, CreateSemaphore)},
+ {"vkCreateShader", offsetof(DeviceVtbl, CreateShader)},
+ {"vkCreateShaderModule", offsetof(DeviceVtbl, CreateShaderModule)},
+ {"vkDestroyAttachmentView", offsetof(DeviceVtbl, DestroyAttachmentView)},
+ {"vkDestroyBuffer", offsetof(DeviceVtbl, DestroyBuffer)},
+ {"vkDestroyBufferView", offsetof(DeviceVtbl, DestroyBufferView)},
+ {"vkDestroyCommandBuffer", offsetof(DeviceVtbl, DestroyCommandBuffer)},
+ {"vkDestroyCommandPool", offsetof(DeviceVtbl, DestroyCommandPool)},
+ {"vkDestroyDescriptorPool", offsetof(DeviceVtbl, DestroyDescriptorPool)},
+ {"vkDestroyDescriptorSetLayout", offsetof(DeviceVtbl, DestroyDescriptorSetLayout)},
+ {"vkDestroyDevice", offsetof(DeviceVtbl, DestroyDevice)},
+ {"vkDestroyDynamicColorBlendState", offsetof(DeviceVtbl, DestroyDynamicColorBlendState)},
+ {"vkDestroyDynamicDepthStencilState", offsetof(DeviceVtbl, DestroyDynamicDepthStencilState)},
+ {"vkDestroyDynamicRasterState", offsetof(DeviceVtbl, DestroyDynamicRasterState)},
+ {"vkDestroyDynamicViewportState", offsetof(DeviceVtbl, DestroyDynamicViewportState)},
+ {"vkDestroyEvent", offsetof(DeviceVtbl, DestroyEvent)},
+ {"vkDestroyFence", offsetof(DeviceVtbl, DestroyFence)},
+ {"vkDestroyFramebuffer", offsetof(DeviceVtbl, DestroyFramebuffer)},
+ {"vkDestroyImage", offsetof(DeviceVtbl, DestroyImage)},
+ {"vkDestroyImageView", offsetof(DeviceVtbl, DestroyImageView)},
+ {"vkDestroyPipeline", offsetof(DeviceVtbl, DestroyPipeline)},
+ {"vkDestroyPipelineCache", offsetof(DeviceVtbl, DestroyPipelineCache)},
+ {"vkDestroyPipelineLayout", offsetof(DeviceVtbl, DestroyPipelineLayout)},
+ {"vkDestroyQueryPool", offsetof(DeviceVtbl, DestroyQueryPool)},
+ {"vkDestroyRenderPass", offsetof(DeviceVtbl, DestroyRenderPass)},
+ {"vkDestroySampler", offsetof(DeviceVtbl, DestroySampler)},
+ {"vkDestroySemaphore", offsetof(DeviceVtbl, DestroySemaphore)},
+ {"vkDestroyShader", offsetof(DeviceVtbl, DestroyShader)},
+ {"vkDestroyShaderModule", offsetof(DeviceVtbl, DestroyShaderModule)},
+ {"vkDeviceWaitIdle", offsetof(DeviceVtbl, DeviceWaitIdle)},
+ {"vkEndCommandBuffer", offsetof(DeviceVtbl, EndCommandBuffer)},
+ {"vkFlushMappedMemoryRanges", offsetof(DeviceVtbl, FlushMappedMemoryRanges)},
+ {"vkFreeDescriptorSets", offsetof(DeviceVtbl, FreeDescriptorSets)},
+ {"vkFreeMemory", offsetof(DeviceVtbl, FreeMemory)},
+ {"vkGetBufferMemoryRequirements", offsetof(DeviceVtbl, GetBufferMemoryRequirements)},
+ {"vkGetDeviceMemoryCommitment", offsetof(DeviceVtbl, GetDeviceMemoryCommitment)},
+ {"vkGetDeviceProcAddr", offsetof(DeviceVtbl, GetDeviceProcAddr)},
+ {"vkGetDeviceQueue", offsetof(DeviceVtbl, GetDeviceQueue)},
+ {"vkGetEventStatus", offsetof(DeviceVtbl, GetEventStatus)},
+ {"vkGetFenceStatus", offsetof(DeviceVtbl, GetFenceStatus)},
+ {"vkGetImageMemoryRequirements", offsetof(DeviceVtbl, GetImageMemoryRequirements)},
+ {"vkGetImageSparseMemoryRequirements", offsetof(DeviceVtbl, GetImageSparseMemoryRequirements)},
+ {"vkGetImageSubresourceLayout", offsetof(DeviceVtbl, GetImageSubresourceLayout)},
+ {"vkGetPipelineCacheData", offsetof(DeviceVtbl, GetPipelineCacheData)},
+ {"vkGetPipelineCacheSize", offsetof(DeviceVtbl, GetPipelineCacheSize)},
+ {"vkGetQueryPoolResults", offsetof(DeviceVtbl, GetQueryPoolResults)},
+ {"vkGetRenderAreaGranularity", offsetof(DeviceVtbl, GetRenderAreaGranularity)},
+ {"vkInvalidateMappedMemoryRanges", offsetof(DeviceVtbl, InvalidateMappedMemoryRanges)},
+ {"vkMapMemory", offsetof(DeviceVtbl, MapMemory)},
+ {"vkMergePipelineCaches", offsetof(DeviceVtbl, MergePipelineCaches)},
+ {"vkQueueBindSparseBufferMemory", offsetof(DeviceVtbl, QueueBindSparseBufferMemory)},
+ {"vkQueueBindSparseImageMemory", offsetof(DeviceVtbl, QueueBindSparseImageMemory)},
+ {"vkQueueBindSparseImageOpaqueMemory", offsetof(DeviceVtbl, QueueBindSparseImageOpaqueMemory)},
+ {"vkQueueSignalSemaphore", offsetof(DeviceVtbl, QueueSignalSemaphore)},
+ {"vkQueueSubmit", offsetof(DeviceVtbl, QueueSubmit)},
+ {"vkQueueWaitIdle", offsetof(DeviceVtbl, QueueWaitIdle)},
+ {"vkQueueWaitSemaphore", offsetof(DeviceVtbl, QueueWaitSemaphore)},
+ {"vkResetCommandBuffer", offsetof(DeviceVtbl, ResetCommandBuffer)},
+ {"vkResetCommandPool", offsetof(DeviceVtbl, ResetCommandPool)},
+ {"vkResetDescriptorPool", offsetof(DeviceVtbl, ResetDescriptorPool)},
+ {"vkResetEvent", offsetof(DeviceVtbl, ResetEvent)},
+ {"vkResetFences", offsetof(DeviceVtbl, ResetFences)},
+ {"vkSetEvent", offsetof(DeviceVtbl, SetEvent)},
+ {"vkUnmapMemory", offsetof(DeviceVtbl, UnmapMemory)},
+ {"vkUpdateDescriptorSets", offsetof(DeviceVtbl, UpdateDescriptorSets)},
+ {"vkWaitForFences", offsetof(DeviceVtbl, WaitForFences)},
+ // clang-format on
+};
+
+} // namespace
+
+namespace vulkan {
+
+PFN_vkVoidFunction GetGlobalInstanceProcAddr(const char* name) {
+ if (strcmp(name, "vkGetDeviceProcAddr") == 0)
+ return reinterpret_cast<PFN_vkVoidFunction>(vkGetDeviceProcAddr);
+ const NameProcEntry* entry = FindProcEntry(kInstanceProcTbl, name);
+ return entry ? entry->proc : nullptr;
+}
+
+PFN_vkVoidFunction GetGlobalDeviceProcAddr(const char* name) {
+ const NameProcEntry* entry = FindProcEntry(kDeviceProcTbl, name);
+ return entry ? entry->proc : nullptr;
+}
+
+PFN_vkVoidFunction GetSpecificInstanceProcAddr(const InstanceVtbl* vtbl,
+ const char* name) {
+ const NameOffsetEntry* entry = FindProcEntry(kInstanceOffsetTbl, name);
+ if (!entry)
+ return nullptr;
+ const unsigned char* base = reinterpret_cast<const unsigned char*>(vtbl);
+ return reinterpret_cast<PFN_vkVoidFunction>(
+ const_cast<unsigned char*>(base) + entry->offset);
+}
+
+PFN_vkVoidFunction GetSpecificDeviceProcAddr(const DeviceVtbl* vtbl,
+ const char* name) {
+ const NameOffsetEntry* entry = FindProcEntry(kDeviceOffsetTbl, name);
+ if (!entry)
+ return nullptr;
+ const unsigned char* base = reinterpret_cast<const unsigned char*>(vtbl);
+ return reinterpret_cast<PFN_vkVoidFunction>(
+ const_cast<unsigned char*>(base) + entry->offset);
+}
+
+bool LoadInstanceVtbl(VkInstance instance,
+ PFN_vkGetInstanceProcAddr get_proc_addr,
+ InstanceVtbl& vtbl) {
+ bool success = true;
+ // clang-format off
+ vtbl.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(get_proc_addr(instance, "vkDestroyInstance"));
+ if (UNLIKELY(!vtbl.DestroyInstance)) {
+ ALOGE("missing instance proc: %s", "vkDestroyInstance");
+ success = false;
+ }
+ vtbl.EnumeratePhysicalDevices = reinterpret_cast<PFN_vkEnumeratePhysicalDevices>(get_proc_addr(instance, "vkEnumeratePhysicalDevices"));
+ if (UNLIKELY(!vtbl.EnumeratePhysicalDevices)) {
+ ALOGE("missing instance proc: %s", "vkEnumeratePhysicalDevices");
+ success = false;
+ }
+ vtbl.GetInstanceProcAddr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(get_proc_addr(instance, "vkGetInstanceProcAddr"));
+ if (UNLIKELY(!vtbl.GetInstanceProcAddr)) {
+ ALOGE("missing instance proc: %s", "vkGetInstanceProcAddr");
+ success = false;
+ }
+ vtbl.GetPhysicalDeviceProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties>(get_proc_addr(instance, "vkGetPhysicalDeviceProperties"));
+ if (UNLIKELY(!vtbl.GetPhysicalDeviceProperties)) {
+ ALOGE("missing instance proc: %s", "vkGetPhysicalDeviceProperties");
+ success = false;
+ }
+ vtbl.GetPhysicalDeviceQueueCount = reinterpret_cast<PFN_vkGetPhysicalDeviceQueueCount>(get_proc_addr(instance, "vkGetPhysicalDeviceQueueCount"));
+ if (UNLIKELY(!vtbl.GetPhysicalDeviceQueueCount)) {
+ ALOGE("missing instance proc: %s", "vkGetPhysicalDeviceQueueCount");
+ success = false;
+ }
+ vtbl.GetPhysicalDeviceQueueProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceQueueProperties>(get_proc_addr(instance, "vkGetPhysicalDeviceQueueProperties"));
+ if (UNLIKELY(!vtbl.GetPhysicalDeviceQueueProperties)) {
+ ALOGE("missing instance proc: %s", "vkGetPhysicalDeviceQueueProperties");
+ success = false;
+ }
+ vtbl.GetPhysicalDeviceMemoryProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceMemoryProperties>(get_proc_addr(instance, "vkGetPhysicalDeviceMemoryProperties"));
+ if (UNLIKELY(!vtbl.GetPhysicalDeviceMemoryProperties)) {
+ ALOGE("missing instance proc: %s", "vkGetPhysicalDeviceMemoryProperties");
+ success = false;
+ }
+ vtbl.GetPhysicalDeviceFeatures = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures>(get_proc_addr(instance, "vkGetPhysicalDeviceFeatures"));
+ if (UNLIKELY(!vtbl.GetPhysicalDeviceFeatures)) {
+ ALOGE("missing instance proc: %s", "vkGetPhysicalDeviceFeatures");
+ success = false;
+ }
+ vtbl.GetPhysicalDeviceFormatProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceFormatProperties>(get_proc_addr(instance, "vkGetPhysicalDeviceFormatProperties"));
+ if (UNLIKELY(!vtbl.GetPhysicalDeviceFormatProperties)) {
+ ALOGE("missing instance proc: %s", "vkGetPhysicalDeviceFormatProperties");
+ success = false;
+ }
+ vtbl.GetPhysicalDeviceImageFormatProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceImageFormatProperties>(get_proc_addr(instance, "vkGetPhysicalDeviceImageFormatProperties"));
+ if (UNLIKELY(!vtbl.GetPhysicalDeviceImageFormatProperties)) {
+ ALOGE("missing instance proc: %s", "vkGetPhysicalDeviceImageFormatProperties");
+ success = false;
+ }
+ vtbl.GetPhysicalDeviceLimits = reinterpret_cast<PFN_vkGetPhysicalDeviceLimits>(get_proc_addr(instance, "vkGetPhysicalDeviceLimits"));
+ if (UNLIKELY(!vtbl.GetPhysicalDeviceLimits)) {
+ ALOGE("missing instance proc: %s", "vkGetPhysicalDeviceLimits");
+ success = false;
+ }
+ vtbl.CreateDevice = reinterpret_cast<PFN_vkCreateDevice>(get_proc_addr(instance, "vkCreateDevice"));
+ if (UNLIKELY(!vtbl.CreateDevice)) {
+ ALOGE("missing instance proc: %s", "vkCreateDevice");
+ success = false;
+ }
+ vtbl.GetPhysicalDeviceLayerProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceLayerProperties>(get_proc_addr(instance, "vkGetPhysicalDeviceLayerProperties"));
+ if (UNLIKELY(!vtbl.GetPhysicalDeviceLayerProperties)) {
+ ALOGE("missing instance proc: %s", "vkGetPhysicalDeviceLayerProperties");
+ success = false;
+ }
+ vtbl.GetPhysicalDeviceExtensionProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceExtensionProperties>(get_proc_addr(instance, "vkGetPhysicalDeviceExtensionProperties"));
+ if (UNLIKELY(!vtbl.GetPhysicalDeviceExtensionProperties)) {
+ ALOGE("missing instance proc: %s", "vkGetPhysicalDeviceExtensionProperties");
+ success = false;
+ }
+ vtbl.GetPhysicalDeviceSparseImageFormatProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceSparseImageFormatProperties>(get_proc_addr(instance, "vkGetPhysicalDeviceSparseImageFormatProperties"));
+ if (UNLIKELY(!vtbl.GetPhysicalDeviceSparseImageFormatProperties)) {
+ ALOGE("missing instance proc: %s", "vkGetPhysicalDeviceSparseImageFormatProperties");
+ success = false;
+ }
+ // clang-format on
+ return success;
+}
+
+bool LoadDeviceVtbl(VkDevice device,
+ PFN_vkGetDeviceProcAddr get_proc_addr,
+ DeviceVtbl& vtbl) {
+ bool success = true;
+ // clang-format off
+ vtbl.GetDeviceProcAddr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(get_proc_addr(device, "vkGetDeviceProcAddr"));
+ if (UNLIKELY(!vtbl.GetDeviceProcAddr)) {
+ ALOGE("missing device proc: %s", "vkGetDeviceProcAddr");
+ success = false;
+ }
+ vtbl.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(get_proc_addr(device, "vkDestroyDevice"));
+ if (UNLIKELY(!vtbl.DestroyDevice)) {
+ ALOGE("missing device proc: %s", "vkDestroyDevice");
+ success = false;
+ }
+ vtbl.GetDeviceQueue = reinterpret_cast<PFN_vkGetDeviceQueue>(get_proc_addr(device, "vkGetDeviceQueue"));
+ if (UNLIKELY(!vtbl.GetDeviceQueue)) {
+ ALOGE("missing device proc: %s", "vkGetDeviceQueue");
+ success = false;
+ }
+ vtbl.QueueSubmit = reinterpret_cast<PFN_vkQueueSubmit>(get_proc_addr(device, "vkQueueSubmit"));
+ if (UNLIKELY(!vtbl.QueueSubmit)) {
+ ALOGE("missing device proc: %s", "vkQueueSubmit");
+ success = false;
+ }
+ vtbl.QueueWaitIdle = reinterpret_cast<PFN_vkQueueWaitIdle>(get_proc_addr(device, "vkQueueWaitIdle"));
+ if (UNLIKELY(!vtbl.QueueWaitIdle)) {
+ ALOGE("missing device proc: %s", "vkQueueWaitIdle");
+ success = false;
+ }
+ vtbl.DeviceWaitIdle = reinterpret_cast<PFN_vkDeviceWaitIdle>(get_proc_addr(device, "vkDeviceWaitIdle"));
+ if (UNLIKELY(!vtbl.DeviceWaitIdle)) {
+ ALOGE("missing device proc: %s", "vkDeviceWaitIdle");
+ success = false;
+ }
+ vtbl.AllocMemory = reinterpret_cast<PFN_vkAllocMemory>(get_proc_addr(device, "vkAllocMemory"));
+ if (UNLIKELY(!vtbl.AllocMemory)) {
+ ALOGE("missing device proc: %s", "vkAllocMemory");
+ success = false;
+ }
+ vtbl.FreeMemory = reinterpret_cast<PFN_vkFreeMemory>(get_proc_addr(device, "vkFreeMemory"));
+ if (UNLIKELY(!vtbl.FreeMemory)) {
+ ALOGE("missing device proc: %s", "vkFreeMemory");
+ success = false;
+ }
+ vtbl.MapMemory = reinterpret_cast<PFN_vkMapMemory>(get_proc_addr(device, "vkMapMemory"));
+ if (UNLIKELY(!vtbl.MapMemory)) {
+ ALOGE("missing device proc: %s", "vkMapMemory");
+ success = false;
+ }
+ vtbl.UnmapMemory = reinterpret_cast<PFN_vkUnmapMemory>(get_proc_addr(device, "vkUnmapMemory"));
+ if (UNLIKELY(!vtbl.UnmapMemory)) {
+ ALOGE("missing device proc: %s", "vkUnmapMemory");
+ success = false;
+ }
+ vtbl.FlushMappedMemoryRanges = reinterpret_cast<PFN_vkFlushMappedMemoryRanges>(get_proc_addr(device, "vkFlushMappedMemoryRanges"));
+ if (UNLIKELY(!vtbl.FlushMappedMemoryRanges)) {
+ ALOGE("missing device proc: %s", "vkFlushMappedMemoryRanges");
+ success = false;
+ }
+ vtbl.InvalidateMappedMemoryRanges = reinterpret_cast<PFN_vkInvalidateMappedMemoryRanges>(get_proc_addr(device, "vkInvalidateMappedMemoryRanges"));
+ if (UNLIKELY(!vtbl.InvalidateMappedMemoryRanges)) {
+ ALOGE("missing device proc: %s", "vkInvalidateMappedMemoryRanges");
+ success = false;
+ }
+ vtbl.GetDeviceMemoryCommitment = reinterpret_cast<PFN_vkGetDeviceMemoryCommitment>(get_proc_addr(device, "vkGetDeviceMemoryCommitment"));
+ if (UNLIKELY(!vtbl.GetDeviceMemoryCommitment)) {
+ ALOGE("missing device proc: %s", "vkGetDeviceMemoryCommitment");
+ success = false;
+ }
+ vtbl.GetBufferMemoryRequirements = reinterpret_cast<PFN_vkGetBufferMemoryRequirements>(get_proc_addr(device, "vkGetBufferMemoryRequirements"));
+ if (UNLIKELY(!vtbl.GetBufferMemoryRequirements)) {
+ ALOGE("missing device proc: %s", "vkGetBufferMemoryRequirements");
+ success = false;
+ }
+ vtbl.BindBufferMemory = reinterpret_cast<PFN_vkBindBufferMemory>(get_proc_addr(device, "vkBindBufferMemory"));
+ if (UNLIKELY(!vtbl.BindBufferMemory)) {
+ ALOGE("missing device proc: %s", "vkBindBufferMemory");
+ success = false;
+ }
+ vtbl.GetImageMemoryRequirements = reinterpret_cast<PFN_vkGetImageMemoryRequirements>(get_proc_addr(device, "vkGetImageMemoryRequirements"));
+ if (UNLIKELY(!vtbl.GetImageMemoryRequirements)) {
+ ALOGE("missing device proc: %s", "vkGetImageMemoryRequirements");
+ success = false;
+ }
+ vtbl.BindImageMemory = reinterpret_cast<PFN_vkBindImageMemory>(get_proc_addr(device, "vkBindImageMemory"));
+ if (UNLIKELY(!vtbl.BindImageMemory)) {
+ ALOGE("missing device proc: %s", "vkBindImageMemory");
+ success = false;
+ }
+ vtbl.GetImageSparseMemoryRequirements = reinterpret_cast<PFN_vkGetImageSparseMemoryRequirements>(get_proc_addr(device, "vkGetImageSparseMemoryRequirements"));
+ if (UNLIKELY(!vtbl.GetImageSparseMemoryRequirements)) {
+ ALOGE("missing device proc: %s", "vkGetImageSparseMemoryRequirements");
+ success = false;
+ }
+ vtbl.QueueBindSparseBufferMemory = reinterpret_cast<PFN_vkQueueBindSparseBufferMemory>(get_proc_addr(device, "vkQueueBindSparseBufferMemory"));
+ if (UNLIKELY(!vtbl.QueueBindSparseBufferMemory)) {
+ ALOGE("missing device proc: %s", "vkQueueBindSparseBufferMemory");
+ success = false;
+ }
+ vtbl.QueueBindSparseImageOpaqueMemory = reinterpret_cast<PFN_vkQueueBindSparseImageOpaqueMemory>(get_proc_addr(device, "vkQueueBindSparseImageOpaqueMemory"));
+ if (UNLIKELY(!vtbl.QueueBindSparseImageOpaqueMemory)) {
+ ALOGE("missing device proc: %s", "vkQueueBindSparseImageOpaqueMemory");
+ success = false;
+ }
+ vtbl.QueueBindSparseImageMemory = reinterpret_cast<PFN_vkQueueBindSparseImageMemory>(get_proc_addr(device, "vkQueueBindSparseImageMemory"));
+ if (UNLIKELY(!vtbl.QueueBindSparseImageMemory)) {
+ ALOGE("missing device proc: %s", "vkQueueBindSparseImageMemory");
+ success = false;
+ }
+ vtbl.CreateFence = reinterpret_cast<PFN_vkCreateFence>(get_proc_addr(device, "vkCreateFence"));
+ if (UNLIKELY(!vtbl.CreateFence)) {
+ ALOGE("missing device proc: %s", "vkCreateFence");
+ success = false;
+ }
+ vtbl.DestroyFence = reinterpret_cast<PFN_vkDestroyFence>(get_proc_addr(device, "vkDestroyFence"));
+ if (UNLIKELY(!vtbl.DestroyFence)) {
+ ALOGE("missing device proc: %s", "vkDestroyFence");
+ success = false;
+ }
+ vtbl.ResetFences = reinterpret_cast<PFN_vkResetFences>(get_proc_addr(device, "vkResetFences"));
+ if (UNLIKELY(!vtbl.ResetFences)) {
+ ALOGE("missing device proc: %s", "vkResetFences");
+ success = false;
+ }
+ vtbl.GetFenceStatus = reinterpret_cast<PFN_vkGetFenceStatus>(get_proc_addr(device, "vkGetFenceStatus"));
+ if (UNLIKELY(!vtbl.GetFenceStatus)) {
+ ALOGE("missing device proc: %s", "vkGetFenceStatus");
+ success = false;
+ }
+ vtbl.WaitForFences = reinterpret_cast<PFN_vkWaitForFences>(get_proc_addr(device, "vkWaitForFences"));
+ if (UNLIKELY(!vtbl.WaitForFences)) {
+ ALOGE("missing device proc: %s", "vkWaitForFences");
+ success = false;
+ }
+ vtbl.CreateSemaphore = reinterpret_cast<PFN_vkCreateSemaphore>(get_proc_addr(device, "vkCreateSemaphore"));
+ if (UNLIKELY(!vtbl.CreateSemaphore)) {
+ ALOGE("missing device proc: %s", "vkCreateSemaphore");
+ success = false;
+ }
+ vtbl.DestroySemaphore = reinterpret_cast<PFN_vkDestroySemaphore>(get_proc_addr(device, "vkDestroySemaphore"));
+ if (UNLIKELY(!vtbl.DestroySemaphore)) {
+ ALOGE("missing device proc: %s", "vkDestroySemaphore");
+ success = false;
+ }
+ vtbl.QueueSignalSemaphore = reinterpret_cast<PFN_vkQueueSignalSemaphore>(get_proc_addr(device, "vkQueueSignalSemaphore"));
+ if (UNLIKELY(!vtbl.QueueSignalSemaphore)) {
+ ALOGE("missing device proc: %s", "vkQueueSignalSemaphore");
+ success = false;
+ }
+ vtbl.QueueWaitSemaphore = reinterpret_cast<PFN_vkQueueWaitSemaphore>(get_proc_addr(device, "vkQueueWaitSemaphore"));
+ if (UNLIKELY(!vtbl.QueueWaitSemaphore)) {
+ ALOGE("missing device proc: %s", "vkQueueWaitSemaphore");
+ success = false;
+ }
+ vtbl.CreateEvent = reinterpret_cast<PFN_vkCreateEvent>(get_proc_addr(device, "vkCreateEvent"));
+ if (UNLIKELY(!vtbl.CreateEvent)) {
+ ALOGE("missing device proc: %s", "vkCreateEvent");
+ success = false;
+ }
+ vtbl.DestroyEvent = reinterpret_cast<PFN_vkDestroyEvent>(get_proc_addr(device, "vkDestroyEvent"));
+ if (UNLIKELY(!vtbl.DestroyEvent)) {
+ ALOGE("missing device proc: %s", "vkDestroyEvent");
+ success = false;
+ }
+ vtbl.GetEventStatus = reinterpret_cast<PFN_vkGetEventStatus>(get_proc_addr(device, "vkGetEventStatus"));
+ if (UNLIKELY(!vtbl.GetEventStatus)) {
+ ALOGE("missing device proc: %s", "vkGetEventStatus");
+ success = false;
+ }
+ vtbl.SetEvent = reinterpret_cast<PFN_vkSetEvent>(get_proc_addr(device, "vkSetEvent"));
+ if (UNLIKELY(!vtbl.SetEvent)) {
+ ALOGE("missing device proc: %s", "vkSetEvent");
+ success = false;
+ }
+ vtbl.ResetEvent = reinterpret_cast<PFN_vkResetEvent>(get_proc_addr(device, "vkResetEvent"));
+ if (UNLIKELY(!vtbl.ResetEvent)) {
+ ALOGE("missing device proc: %s", "vkResetEvent");
+ success = false;
+ }
+ vtbl.CreateQueryPool = reinterpret_cast<PFN_vkCreateQueryPool>(get_proc_addr(device, "vkCreateQueryPool"));
+ if (UNLIKELY(!vtbl.CreateQueryPool)) {
+ ALOGE("missing device proc: %s", "vkCreateQueryPool");
+ success = false;
+ }
+ vtbl.DestroyQueryPool = reinterpret_cast<PFN_vkDestroyQueryPool>(get_proc_addr(device, "vkDestroyQueryPool"));
+ if (UNLIKELY(!vtbl.DestroyQueryPool)) {
+ ALOGE("missing device proc: %s", "vkDestroyQueryPool");
+ success = false;
+ }
+ vtbl.GetQueryPoolResults = reinterpret_cast<PFN_vkGetQueryPoolResults>(get_proc_addr(device, "vkGetQueryPoolResults"));
+ if (UNLIKELY(!vtbl.GetQueryPoolResults)) {
+ ALOGE("missing device proc: %s", "vkGetQueryPoolResults");
+ success = false;
+ }
+ vtbl.CreateBuffer = reinterpret_cast<PFN_vkCreateBuffer>(get_proc_addr(device, "vkCreateBuffer"));
+ if (UNLIKELY(!vtbl.CreateBuffer)) {
+ ALOGE("missing device proc: %s", "vkCreateBuffer");
+ success = false;
+ }
+ vtbl.DestroyBuffer = reinterpret_cast<PFN_vkDestroyBuffer>(get_proc_addr(device, "vkDestroyBuffer"));
+ if (UNLIKELY(!vtbl.DestroyBuffer)) {
+ ALOGE("missing device proc: %s", "vkDestroyBuffer");
+ success = false;
+ }
+ vtbl.CreateBufferView = reinterpret_cast<PFN_vkCreateBufferView>(get_proc_addr(device, "vkCreateBufferView"));
+ if (UNLIKELY(!vtbl.CreateBufferView)) {
+ ALOGE("missing device proc: %s", "vkCreateBufferView");
+ success = false;
+ }
+ vtbl.DestroyBufferView = reinterpret_cast<PFN_vkDestroyBufferView>(get_proc_addr(device, "vkDestroyBufferView"));
+ if (UNLIKELY(!vtbl.DestroyBufferView)) {
+ ALOGE("missing device proc: %s", "vkDestroyBufferView");
+ success = false;
+ }
+ vtbl.CreateImage = reinterpret_cast<PFN_vkCreateImage>(get_proc_addr(device, "vkCreateImage"));
+ if (UNLIKELY(!vtbl.CreateImage)) {
+ ALOGE("missing device proc: %s", "vkCreateImage");
+ success = false;
+ }
+ vtbl.DestroyImage = reinterpret_cast<PFN_vkDestroyImage>(get_proc_addr(device, "vkDestroyImage"));
+ if (UNLIKELY(!vtbl.DestroyImage)) {
+ ALOGE("missing device proc: %s", "vkDestroyImage");
+ success = false;
+ }
+ vtbl.GetImageSubresourceLayout = reinterpret_cast<PFN_vkGetImageSubresourceLayout>(get_proc_addr(device, "vkGetImageSubresourceLayout"));
+ if (UNLIKELY(!vtbl.GetImageSubresourceLayout)) {
+ ALOGE("missing device proc: %s", "vkGetImageSubresourceLayout");
+ success = false;
+ }
+ vtbl.CreateImageView = reinterpret_cast<PFN_vkCreateImageView>(get_proc_addr(device, "vkCreateImageView"));
+ if (UNLIKELY(!vtbl.CreateImageView)) {
+ ALOGE("missing device proc: %s", "vkCreateImageView");
+ success = false;
+ }
+ vtbl.DestroyImageView = reinterpret_cast<PFN_vkDestroyImageView>(get_proc_addr(device, "vkDestroyImageView"));
+ if (UNLIKELY(!vtbl.DestroyImageView)) {
+ ALOGE("missing device proc: %s", "vkDestroyImageView");
+ success = false;
+ }
+ vtbl.CreateAttachmentView = reinterpret_cast<PFN_vkCreateAttachmentView>(get_proc_addr(device, "vkCreateAttachmentView"));
+ if (UNLIKELY(!vtbl.CreateAttachmentView)) {
+ ALOGE("missing device proc: %s", "vkCreateAttachmentView");
+ success = false;
+ }
+ vtbl.DestroyAttachmentView = reinterpret_cast<PFN_vkDestroyAttachmentView>(get_proc_addr(device, "vkDestroyAttachmentView"));
+ if (UNLIKELY(!vtbl.DestroyAttachmentView)) {
+ ALOGE("missing device proc: %s", "vkDestroyAttachmentView");
+ success = false;
+ }
+ vtbl.CreateShaderModule = reinterpret_cast<PFN_vkCreateShaderModule>(get_proc_addr(device, "vkCreateShaderModule"));
+ if (UNLIKELY(!vtbl.CreateShaderModule)) {
+ ALOGE("missing device proc: %s", "vkCreateShaderModule");
+ success = false;
+ }
+ vtbl.DestroyShaderModule = reinterpret_cast<PFN_vkDestroyShaderModule>(get_proc_addr(device, "vkDestroyShaderModule"));
+ if (UNLIKELY(!vtbl.DestroyShaderModule)) {
+ ALOGE("missing device proc: %s", "vkDestroyShaderModule");
+ success = false;
+ }
+ vtbl.CreateShader = reinterpret_cast<PFN_vkCreateShader>(get_proc_addr(device, "vkCreateShader"));
+ if (UNLIKELY(!vtbl.CreateShader)) {
+ ALOGE("missing device proc: %s", "vkCreateShader");
+ success = false;
+ }
+ vtbl.DestroyShader = reinterpret_cast<PFN_vkDestroyShader>(get_proc_addr(device, "vkDestroyShader"));
+ if (UNLIKELY(!vtbl.DestroyShader)) {
+ ALOGE("missing device proc: %s", "vkDestroyShader");
+ success = false;
+ }
+ vtbl.CreatePipelineCache = reinterpret_cast<PFN_vkCreatePipelineCache>(get_proc_addr(device, "vkCreatePipelineCache"));
+ if (UNLIKELY(!vtbl.CreatePipelineCache)) {
+ ALOGE("missing device proc: %s", "vkCreatePipelineCache");
+ success = false;
+ }
+ vtbl.DestroyPipelineCache = reinterpret_cast<PFN_vkDestroyPipelineCache>(get_proc_addr(device, "vkDestroyPipelineCache"));
+ if (UNLIKELY(!vtbl.DestroyPipelineCache)) {
+ ALOGE("missing device proc: %s", "vkDestroyPipelineCache");
+ success = false;
+ }
+ vtbl.GetPipelineCacheSize = reinterpret_cast<PFN_vkGetPipelineCacheSize>(get_proc_addr(device, "vkGetPipelineCacheSize"));
+ if (UNLIKELY(!vtbl.GetPipelineCacheSize)) {
+ ALOGE("missing device proc: %s", "vkGetPipelineCacheSize");
+ success = false;
+ }
+ vtbl.GetPipelineCacheData = reinterpret_cast<PFN_vkGetPipelineCacheData>(get_proc_addr(device, "vkGetPipelineCacheData"));
+ if (UNLIKELY(!vtbl.GetPipelineCacheData)) {
+ ALOGE("missing device proc: %s", "vkGetPipelineCacheData");
+ success = false;
+ }
+ vtbl.MergePipelineCaches = reinterpret_cast<PFN_vkMergePipelineCaches>(get_proc_addr(device, "vkMergePipelineCaches"));
+ if (UNLIKELY(!vtbl.MergePipelineCaches)) {
+ ALOGE("missing device proc: %s", "vkMergePipelineCaches");
+ success = false;
+ }
+ vtbl.CreateGraphicsPipelines = reinterpret_cast<PFN_vkCreateGraphicsPipelines>(get_proc_addr(device, "vkCreateGraphicsPipelines"));
+ if (UNLIKELY(!vtbl.CreateGraphicsPipelines)) {
+ ALOGE("missing device proc: %s", "vkCreateGraphicsPipelines");
+ success = false;
+ }
+ vtbl.CreateComputePipelines = reinterpret_cast<PFN_vkCreateComputePipelines>(get_proc_addr(device, "vkCreateComputePipelines"));
+ if (UNLIKELY(!vtbl.CreateComputePipelines)) {
+ ALOGE("missing device proc: %s", "vkCreateComputePipelines");
+ success = false;
+ }
+ vtbl.DestroyPipeline = reinterpret_cast<PFN_vkDestroyPipeline>(get_proc_addr(device, "vkDestroyPipeline"));
+ if (UNLIKELY(!vtbl.DestroyPipeline)) {
+ ALOGE("missing device proc: %s", "vkDestroyPipeline");
+ success = false;
+ }
+ vtbl.CreatePipelineLayout = reinterpret_cast<PFN_vkCreatePipelineLayout>(get_proc_addr(device, "vkCreatePipelineLayout"));
+ if (UNLIKELY(!vtbl.CreatePipelineLayout)) {
+ ALOGE("missing device proc: %s", "vkCreatePipelineLayout");
+ success = false;
+ }
+ vtbl.DestroyPipelineLayout = reinterpret_cast<PFN_vkDestroyPipelineLayout>(get_proc_addr(device, "vkDestroyPipelineLayout"));
+ if (UNLIKELY(!vtbl.DestroyPipelineLayout)) {
+ ALOGE("missing device proc: %s", "vkDestroyPipelineLayout");
+ success = false;
+ }
+ vtbl.CreateSampler = reinterpret_cast<PFN_vkCreateSampler>(get_proc_addr(device, "vkCreateSampler"));
+ if (UNLIKELY(!vtbl.CreateSampler)) {
+ ALOGE("missing device proc: %s", "vkCreateSampler");
+ success = false;
+ }
+ vtbl.DestroySampler = reinterpret_cast<PFN_vkDestroySampler>(get_proc_addr(device, "vkDestroySampler"));
+ if (UNLIKELY(!vtbl.DestroySampler)) {
+ ALOGE("missing device proc: %s", "vkDestroySampler");
+ success = false;
+ }
+ vtbl.CreateDescriptorSetLayout = reinterpret_cast<PFN_vkCreateDescriptorSetLayout>(get_proc_addr(device, "vkCreateDescriptorSetLayout"));
+ if (UNLIKELY(!vtbl.CreateDescriptorSetLayout)) {
+ ALOGE("missing device proc: %s", "vkCreateDescriptorSetLayout");
+ success = false;
+ }
+ vtbl.DestroyDescriptorSetLayout = reinterpret_cast<PFN_vkDestroyDescriptorSetLayout>(get_proc_addr(device, "vkDestroyDescriptorSetLayout"));
+ if (UNLIKELY(!vtbl.DestroyDescriptorSetLayout)) {
+ ALOGE("missing device proc: %s", "vkDestroyDescriptorSetLayout");
+ success = false;
+ }
+ vtbl.CreateDescriptorPool = reinterpret_cast<PFN_vkCreateDescriptorPool>(get_proc_addr(device, "vkCreateDescriptorPool"));
+ if (UNLIKELY(!vtbl.CreateDescriptorPool)) {
+ ALOGE("missing device proc: %s", "vkCreateDescriptorPool");
+ success = false;
+ }
+ vtbl.DestroyDescriptorPool = reinterpret_cast<PFN_vkDestroyDescriptorPool>(get_proc_addr(device, "vkDestroyDescriptorPool"));
+ if (UNLIKELY(!vtbl.DestroyDescriptorPool)) {
+ ALOGE("missing device proc: %s", "vkDestroyDescriptorPool");
+ success = false;
+ }
+ vtbl.ResetDescriptorPool = reinterpret_cast<PFN_vkResetDescriptorPool>(get_proc_addr(device, "vkResetDescriptorPool"));
+ if (UNLIKELY(!vtbl.ResetDescriptorPool)) {
+ ALOGE("missing device proc: %s", "vkResetDescriptorPool");
+ success = false;
+ }
+ vtbl.AllocDescriptorSets = reinterpret_cast<PFN_vkAllocDescriptorSets>(get_proc_addr(device, "vkAllocDescriptorSets"));
+ if (UNLIKELY(!vtbl.AllocDescriptorSets)) {
+ ALOGE("missing device proc: %s", "vkAllocDescriptorSets");
+ success = false;
+ }
+ vtbl.FreeDescriptorSets = reinterpret_cast<PFN_vkFreeDescriptorSets>(get_proc_addr(device, "vkFreeDescriptorSets"));
+ if (UNLIKELY(!vtbl.FreeDescriptorSets)) {
+ ALOGE("missing device proc: %s", "vkFreeDescriptorSets");
+ success = false;
+ }
+ vtbl.UpdateDescriptorSets = reinterpret_cast<PFN_vkUpdateDescriptorSets>(get_proc_addr(device, "vkUpdateDescriptorSets"));
+ if (UNLIKELY(!vtbl.UpdateDescriptorSets)) {
+ ALOGE("missing device proc: %s", "vkUpdateDescriptorSets");
+ success = false;
+ }
+ vtbl.CreateDynamicViewportState = reinterpret_cast<PFN_vkCreateDynamicViewportState>(get_proc_addr(device, "vkCreateDynamicViewportState"));
+ if (UNLIKELY(!vtbl.CreateDynamicViewportState)) {
+ ALOGE("missing device proc: %s", "vkCreateDynamicViewportState");
+ success = false;
+ }
+ vtbl.DestroyDynamicViewportState = reinterpret_cast<PFN_vkDestroyDynamicViewportState>(get_proc_addr(device, "vkDestroyDynamicViewportState"));
+ if (UNLIKELY(!vtbl.DestroyDynamicViewportState)) {
+ ALOGE("missing device proc: %s", "vkDestroyDynamicViewportState");
+ success = false;
+ }
+ vtbl.CreateDynamicRasterState = reinterpret_cast<PFN_vkCreateDynamicRasterState>(get_proc_addr(device, "vkCreateDynamicRasterState"));
+ if (UNLIKELY(!vtbl.CreateDynamicRasterState)) {
+ ALOGE("missing device proc: %s", "vkCreateDynamicRasterState");
+ success = false;
+ }
+ vtbl.DestroyDynamicRasterState = reinterpret_cast<PFN_vkDestroyDynamicRasterState>(get_proc_addr(device, "vkDestroyDynamicRasterState"));
+ if (UNLIKELY(!vtbl.DestroyDynamicRasterState)) {
+ ALOGE("missing device proc: %s", "vkDestroyDynamicRasterState");
+ success = false;
+ }
+ vtbl.CreateDynamicColorBlendState = reinterpret_cast<PFN_vkCreateDynamicColorBlendState>(get_proc_addr(device, "vkCreateDynamicColorBlendState"));
+ if (UNLIKELY(!vtbl.CreateDynamicColorBlendState)) {
+ ALOGE("missing device proc: %s", "vkCreateDynamicColorBlendState");
+ success = false;
+ }
+ vtbl.DestroyDynamicColorBlendState = reinterpret_cast<PFN_vkDestroyDynamicColorBlendState>(get_proc_addr(device, "vkDestroyDynamicColorBlendState"));
+ if (UNLIKELY(!vtbl.DestroyDynamicColorBlendState)) {
+ ALOGE("missing device proc: %s", "vkDestroyDynamicColorBlendState");
+ success = false;
+ }
+ vtbl.CreateDynamicDepthStencilState = reinterpret_cast<PFN_vkCreateDynamicDepthStencilState>(get_proc_addr(device, "vkCreateDynamicDepthStencilState"));
+ if (UNLIKELY(!vtbl.CreateDynamicDepthStencilState)) {
+ ALOGE("missing device proc: %s", "vkCreateDynamicDepthStencilState");
+ success = false;
+ }
+ vtbl.DestroyDynamicDepthStencilState = reinterpret_cast<PFN_vkDestroyDynamicDepthStencilState>(get_proc_addr(device, "vkDestroyDynamicDepthStencilState"));
+ if (UNLIKELY(!vtbl.DestroyDynamicDepthStencilState)) {
+ ALOGE("missing device proc: %s", "vkDestroyDynamicDepthStencilState");
+ success = false;
+ }
+ vtbl.CreateFramebuffer = reinterpret_cast<PFN_vkCreateFramebuffer>(get_proc_addr(device, "vkCreateFramebuffer"));
+ if (UNLIKELY(!vtbl.CreateFramebuffer)) {
+ ALOGE("missing device proc: %s", "vkCreateFramebuffer");
+ success = false;
+ }
+ vtbl.DestroyFramebuffer = reinterpret_cast<PFN_vkDestroyFramebuffer>(get_proc_addr(device, "vkDestroyFramebuffer"));
+ if (UNLIKELY(!vtbl.DestroyFramebuffer)) {
+ ALOGE("missing device proc: %s", "vkDestroyFramebuffer");
+ success = false;
+ }
+ vtbl.CreateRenderPass = reinterpret_cast<PFN_vkCreateRenderPass>(get_proc_addr(device, "vkCreateRenderPass"));
+ if (UNLIKELY(!vtbl.CreateRenderPass)) {
+ ALOGE("missing device proc: %s", "vkCreateRenderPass");
+ success = false;
+ }
+ vtbl.DestroyRenderPass = reinterpret_cast<PFN_vkDestroyRenderPass>(get_proc_addr(device, "vkDestroyRenderPass"));
+ if (UNLIKELY(!vtbl.DestroyRenderPass)) {
+ ALOGE("missing device proc: %s", "vkDestroyRenderPass");
+ success = false;
+ }
+ vtbl.GetRenderAreaGranularity = reinterpret_cast<PFN_vkGetRenderAreaGranularity>(get_proc_addr(device, "vkGetRenderAreaGranularity"));
+ if (UNLIKELY(!vtbl.GetRenderAreaGranularity)) {
+ ALOGE("missing device proc: %s", "vkGetRenderAreaGranularity");
+ success = false;
+ }
+ vtbl.CreateCommandPool = reinterpret_cast<PFN_vkCreateCommandPool>(get_proc_addr(device, "vkCreateCommandPool"));
+ if (UNLIKELY(!vtbl.CreateCommandPool)) {
+ ALOGE("missing device proc: %s", "vkCreateCommandPool");
+ success = false;
+ }
+ vtbl.DestroyCommandPool = reinterpret_cast<PFN_vkDestroyCommandPool>(get_proc_addr(device, "vkDestroyCommandPool"));
+ if (UNLIKELY(!vtbl.DestroyCommandPool)) {
+ ALOGE("missing device proc: %s", "vkDestroyCommandPool");
+ success = false;
+ }
+ vtbl.ResetCommandPool = reinterpret_cast<PFN_vkResetCommandPool>(get_proc_addr(device, "vkResetCommandPool"));
+ if (UNLIKELY(!vtbl.ResetCommandPool)) {
+ ALOGE("missing device proc: %s", "vkResetCommandPool");
+ success = false;
+ }
+ vtbl.CreateCommandBuffer = reinterpret_cast<PFN_vkCreateCommandBuffer>(get_proc_addr(device, "vkCreateCommandBuffer"));
+ if (UNLIKELY(!vtbl.CreateCommandBuffer)) {
+ ALOGE("missing device proc: %s", "vkCreateCommandBuffer");
+ success = false;
+ }
+ vtbl.DestroyCommandBuffer = reinterpret_cast<PFN_vkDestroyCommandBuffer>(get_proc_addr(device, "vkDestroyCommandBuffer"));
+ if (UNLIKELY(!vtbl.DestroyCommandBuffer)) {
+ ALOGE("missing device proc: %s", "vkDestroyCommandBuffer");
+ success = false;
+ }
+ vtbl.BeginCommandBuffer = reinterpret_cast<PFN_vkBeginCommandBuffer>(get_proc_addr(device, "vkBeginCommandBuffer"));
+ if (UNLIKELY(!vtbl.BeginCommandBuffer)) {
+ ALOGE("missing device proc: %s", "vkBeginCommandBuffer");
+ success = false;
+ }
+ vtbl.EndCommandBuffer = reinterpret_cast<PFN_vkEndCommandBuffer>(get_proc_addr(device, "vkEndCommandBuffer"));
+ if (UNLIKELY(!vtbl.EndCommandBuffer)) {
+ ALOGE("missing device proc: %s", "vkEndCommandBuffer");
+ success = false;
+ }
+ vtbl.ResetCommandBuffer = reinterpret_cast<PFN_vkResetCommandBuffer>(get_proc_addr(device, "vkResetCommandBuffer"));
+ if (UNLIKELY(!vtbl.ResetCommandBuffer)) {
+ ALOGE("missing device proc: %s", "vkResetCommandBuffer");
+ success = false;
+ }
+ vtbl.CmdBindPipeline = reinterpret_cast<PFN_vkCmdBindPipeline>(get_proc_addr(device, "vkCmdBindPipeline"));
+ if (UNLIKELY(!vtbl.CmdBindPipeline)) {
+ ALOGE("missing device proc: %s", "vkCmdBindPipeline");
+ success = false;
+ }
+ vtbl.CmdBindDynamicViewportState = reinterpret_cast<PFN_vkCmdBindDynamicViewportState>(get_proc_addr(device, "vkCmdBindDynamicViewportState"));
+ if (UNLIKELY(!vtbl.CmdBindDynamicViewportState)) {
+ ALOGE("missing device proc: %s", "vkCmdBindDynamicViewportState");
+ success = false;
+ }
+ vtbl.CmdBindDynamicRasterState = reinterpret_cast<PFN_vkCmdBindDynamicRasterState>(get_proc_addr(device, "vkCmdBindDynamicRasterState"));
+ if (UNLIKELY(!vtbl.CmdBindDynamicRasterState)) {
+ ALOGE("missing device proc: %s", "vkCmdBindDynamicRasterState");
+ success = false;
+ }
+ vtbl.CmdBindDynamicColorBlendState = reinterpret_cast<PFN_vkCmdBindDynamicColorBlendState>(get_proc_addr(device, "vkCmdBindDynamicColorBlendState"));
+ if (UNLIKELY(!vtbl.CmdBindDynamicColorBlendState)) {
+ ALOGE("missing device proc: %s", "vkCmdBindDynamicColorBlendState");
+ success = false;
+ }
+ vtbl.CmdBindDynamicDepthStencilState = reinterpret_cast<PFN_vkCmdBindDynamicDepthStencilState>(get_proc_addr(device, "vkCmdBindDynamicDepthStencilState"));
+ if (UNLIKELY(!vtbl.CmdBindDynamicDepthStencilState)) {
+ ALOGE("missing device proc: %s", "vkCmdBindDynamicDepthStencilState");
+ success = false;
+ }
+ vtbl.CmdBindDescriptorSets = reinterpret_cast<PFN_vkCmdBindDescriptorSets>(get_proc_addr(device, "vkCmdBindDescriptorSets"));
+ if (UNLIKELY(!vtbl.CmdBindDescriptorSets)) {
+ ALOGE("missing device proc: %s", "vkCmdBindDescriptorSets");
+ success = false;
+ }
+ vtbl.CmdBindIndexBuffer = reinterpret_cast<PFN_vkCmdBindIndexBuffer>(get_proc_addr(device, "vkCmdBindIndexBuffer"));
+ if (UNLIKELY(!vtbl.CmdBindIndexBuffer)) {
+ ALOGE("missing device proc: %s", "vkCmdBindIndexBuffer");
+ success = false;
+ }
+ vtbl.CmdBindVertexBuffers = reinterpret_cast<PFN_vkCmdBindVertexBuffers>(get_proc_addr(device, "vkCmdBindVertexBuffers"));
+ if (UNLIKELY(!vtbl.CmdBindVertexBuffers)) {
+ ALOGE("missing device proc: %s", "vkCmdBindVertexBuffers");
+ success = false;
+ }
+ vtbl.CmdDraw = reinterpret_cast<PFN_vkCmdDraw>(get_proc_addr(device, "vkCmdDraw"));
+ if (UNLIKELY(!vtbl.CmdDraw)) {
+ ALOGE("missing device proc: %s", "vkCmdDraw");
+ success = false;
+ }
+ vtbl.CmdDrawIndexed = reinterpret_cast<PFN_vkCmdDrawIndexed>(get_proc_addr(device, "vkCmdDrawIndexed"));
+ if (UNLIKELY(!vtbl.CmdDrawIndexed)) {
+ ALOGE("missing device proc: %s", "vkCmdDrawIndexed");
+ success = false;
+ }
+ vtbl.CmdDrawIndirect = reinterpret_cast<PFN_vkCmdDrawIndirect>(get_proc_addr(device, "vkCmdDrawIndirect"));
+ if (UNLIKELY(!vtbl.CmdDrawIndirect)) {
+ ALOGE("missing device proc: %s", "vkCmdDrawIndirect");
+ success = false;
+ }
+ vtbl.CmdDrawIndexedIndirect = reinterpret_cast<PFN_vkCmdDrawIndexedIndirect>(get_proc_addr(device, "vkCmdDrawIndexedIndirect"));
+ if (UNLIKELY(!vtbl.CmdDrawIndexedIndirect)) {
+ ALOGE("missing device proc: %s", "vkCmdDrawIndexedIndirect");
+ success = false;
+ }
+ vtbl.CmdDispatch = reinterpret_cast<PFN_vkCmdDispatch>(get_proc_addr(device, "vkCmdDispatch"));
+ if (UNLIKELY(!vtbl.CmdDispatch)) {
+ ALOGE("missing device proc: %s", "vkCmdDispatch");
+ success = false;
+ }
+ vtbl.CmdDispatchIndirect = reinterpret_cast<PFN_vkCmdDispatchIndirect>(get_proc_addr(device, "vkCmdDispatchIndirect"));
+ if (UNLIKELY(!vtbl.CmdDispatchIndirect)) {
+ ALOGE("missing device proc: %s", "vkCmdDispatchIndirect");
+ success = false;
+ }
+ vtbl.CmdCopyBuffer = reinterpret_cast<PFN_vkCmdCopyBuffer>(get_proc_addr(device, "vkCmdCopyBuffer"));
+ if (UNLIKELY(!vtbl.CmdCopyBuffer)) {
+ ALOGE("missing device proc: %s", "vkCmdCopyBuffer");
+ success = false;
+ }
+ vtbl.CmdCopyImage = reinterpret_cast<PFN_vkCmdCopyImage>(get_proc_addr(device, "vkCmdCopyImage"));
+ if (UNLIKELY(!vtbl.CmdCopyImage)) {
+ ALOGE("missing device proc: %s", "vkCmdCopyImage");
+ success = false;
+ }
+ vtbl.CmdBlitImage = reinterpret_cast<PFN_vkCmdBlitImage>(get_proc_addr(device, "vkCmdBlitImage"));
+ if (UNLIKELY(!vtbl.CmdBlitImage)) {
+ ALOGE("missing device proc: %s", "vkCmdBlitImage");
+ success = false;
+ }
+ vtbl.CmdCopyBufferToImage = reinterpret_cast<PFN_vkCmdCopyBufferToImage>(get_proc_addr(device, "vkCmdCopyBufferToImage"));
+ if (UNLIKELY(!vtbl.CmdCopyBufferToImage)) {
+ ALOGE("missing device proc: %s", "vkCmdCopyBufferToImage");
+ success = false;
+ }
+ vtbl.CmdCopyImageToBuffer = reinterpret_cast<PFN_vkCmdCopyImageToBuffer>(get_proc_addr(device, "vkCmdCopyImageToBuffer"));
+ if (UNLIKELY(!vtbl.CmdCopyImageToBuffer)) {
+ ALOGE("missing device proc: %s", "vkCmdCopyImageToBuffer");
+ success = false;
+ }
+ vtbl.CmdUpdateBuffer = reinterpret_cast<PFN_vkCmdUpdateBuffer>(get_proc_addr(device, "vkCmdUpdateBuffer"));
+ if (UNLIKELY(!vtbl.CmdUpdateBuffer)) {
+ ALOGE("missing device proc: %s", "vkCmdUpdateBuffer");
+ success = false;
+ }
+ vtbl.CmdFillBuffer = reinterpret_cast<PFN_vkCmdFillBuffer>(get_proc_addr(device, "vkCmdFillBuffer"));
+ if (UNLIKELY(!vtbl.CmdFillBuffer)) {
+ ALOGE("missing device proc: %s", "vkCmdFillBuffer");
+ success = false;
+ }
+ vtbl.CmdClearColorImage = reinterpret_cast<PFN_vkCmdClearColorImage>(get_proc_addr(device, "vkCmdClearColorImage"));
+ if (UNLIKELY(!vtbl.CmdClearColorImage)) {
+ ALOGE("missing device proc: %s", "vkCmdClearColorImage");
+ success = false;
+ }
+ vtbl.CmdClearDepthStencilImage = reinterpret_cast<PFN_vkCmdClearDepthStencilImage>(get_proc_addr(device, "vkCmdClearDepthStencilImage"));
+ if (UNLIKELY(!vtbl.CmdClearDepthStencilImage)) {
+ ALOGE("missing device proc: %s", "vkCmdClearDepthStencilImage");
+ success = false;
+ }
+ vtbl.CmdClearColorAttachment = reinterpret_cast<PFN_vkCmdClearColorAttachment>(get_proc_addr(device, "vkCmdClearColorAttachment"));
+ if (UNLIKELY(!vtbl.CmdClearColorAttachment)) {
+ ALOGE("missing device proc: %s", "vkCmdClearColorAttachment");
+ success = false;
+ }
+ vtbl.CmdClearDepthStencilAttachment = reinterpret_cast<PFN_vkCmdClearDepthStencilAttachment>(get_proc_addr(device, "vkCmdClearDepthStencilAttachment"));
+ if (UNLIKELY(!vtbl.CmdClearDepthStencilAttachment)) {
+ ALOGE("missing device proc: %s", "vkCmdClearDepthStencilAttachment");
+ success = false;
+ }
+ vtbl.CmdResolveImage = reinterpret_cast<PFN_vkCmdResolveImage>(get_proc_addr(device, "vkCmdResolveImage"));
+ if (UNLIKELY(!vtbl.CmdResolveImage)) {
+ ALOGE("missing device proc: %s", "vkCmdResolveImage");
+ success = false;
+ }
+ vtbl.CmdSetEvent = reinterpret_cast<PFN_vkCmdSetEvent>(get_proc_addr(device, "vkCmdSetEvent"));
+ if (UNLIKELY(!vtbl.CmdSetEvent)) {
+ ALOGE("missing device proc: %s", "vkCmdSetEvent");
+ success = false;
+ }
+ vtbl.CmdResetEvent = reinterpret_cast<PFN_vkCmdResetEvent>(get_proc_addr(device, "vkCmdResetEvent"));
+ if (UNLIKELY(!vtbl.CmdResetEvent)) {
+ ALOGE("missing device proc: %s", "vkCmdResetEvent");
+ success = false;
+ }
+ vtbl.CmdWaitEvents = reinterpret_cast<PFN_vkCmdWaitEvents>(get_proc_addr(device, "vkCmdWaitEvents"));
+ if (UNLIKELY(!vtbl.CmdWaitEvents)) {
+ ALOGE("missing device proc: %s", "vkCmdWaitEvents");
+ success = false;
+ }
+ vtbl.CmdPipelineBarrier = reinterpret_cast<PFN_vkCmdPipelineBarrier>(get_proc_addr(device, "vkCmdPipelineBarrier"));
+ if (UNLIKELY(!vtbl.CmdPipelineBarrier)) {
+ ALOGE("missing device proc: %s", "vkCmdPipelineBarrier");
+ success = false;
+ }
+ vtbl.CmdBeginQuery = reinterpret_cast<PFN_vkCmdBeginQuery>(get_proc_addr(device, "vkCmdBeginQuery"));
+ if (UNLIKELY(!vtbl.CmdBeginQuery)) {
+ ALOGE("missing device proc: %s", "vkCmdBeginQuery");
+ success = false;
+ }
+ vtbl.CmdEndQuery = reinterpret_cast<PFN_vkCmdEndQuery>(get_proc_addr(device, "vkCmdEndQuery"));
+ if (UNLIKELY(!vtbl.CmdEndQuery)) {
+ ALOGE("missing device proc: %s", "vkCmdEndQuery");
+ success = false;
+ }
+ vtbl.CmdResetQueryPool = reinterpret_cast<PFN_vkCmdResetQueryPool>(get_proc_addr(device, "vkCmdResetQueryPool"));
+ if (UNLIKELY(!vtbl.CmdResetQueryPool)) {
+ ALOGE("missing device proc: %s", "vkCmdResetQueryPool");
+ success = false;
+ }
+ vtbl.CmdWriteTimestamp = reinterpret_cast<PFN_vkCmdWriteTimestamp>(get_proc_addr(device, "vkCmdWriteTimestamp"));
+ if (UNLIKELY(!vtbl.CmdWriteTimestamp)) {
+ ALOGE("missing device proc: %s", "vkCmdWriteTimestamp");
+ success = false;
+ }
+ vtbl.CmdCopyQueryPoolResults = reinterpret_cast<PFN_vkCmdCopyQueryPoolResults>(get_proc_addr(device, "vkCmdCopyQueryPoolResults"));
+ if (UNLIKELY(!vtbl.CmdCopyQueryPoolResults)) {
+ ALOGE("missing device proc: %s", "vkCmdCopyQueryPoolResults");
+ success = false;
+ }
+ vtbl.CmdPushConstants = reinterpret_cast<PFN_vkCmdPushConstants>(get_proc_addr(device, "vkCmdPushConstants"));
+ if (UNLIKELY(!vtbl.CmdPushConstants)) {
+ ALOGE("missing device proc: %s", "vkCmdPushConstants");
+ success = false;
+ }
+ vtbl.CmdBeginRenderPass = reinterpret_cast<PFN_vkCmdBeginRenderPass>(get_proc_addr(device, "vkCmdBeginRenderPass"));
+ if (UNLIKELY(!vtbl.CmdBeginRenderPass)) {
+ ALOGE("missing device proc: %s", "vkCmdBeginRenderPass");
+ success = false;
+ }
+ vtbl.CmdNextSubpass = reinterpret_cast<PFN_vkCmdNextSubpass>(get_proc_addr(device, "vkCmdNextSubpass"));
+ if (UNLIKELY(!vtbl.CmdNextSubpass)) {
+ ALOGE("missing device proc: %s", "vkCmdNextSubpass");
+ success = false;
+ }
+ vtbl.CmdEndRenderPass = reinterpret_cast<PFN_vkCmdEndRenderPass>(get_proc_addr(device, "vkCmdEndRenderPass"));
+ if (UNLIKELY(!vtbl.CmdEndRenderPass)) {
+ ALOGE("missing device proc: %s", "vkCmdEndRenderPass");
+ success = false;
+ }
+ vtbl.CmdExecuteCommands = reinterpret_cast<PFN_vkCmdExecuteCommands>(get_proc_addr(device, "vkCmdExecuteCommands"));
+ if (UNLIKELY(!vtbl.CmdExecuteCommands)) {
+ ALOGE("missing device proc: %s", "vkCmdExecuteCommands");
+ success = false;
+ }
+ // clang-format on
+ return success;
+}
+
+} // namespace vulkan
diff --git a/vulkan/libvulkan/get_proc_addr.cpp.tmpl b/vulkan/libvulkan/get_proc_addr.cpp.tmpl
new file mode 100644
index 0000000..d4ced56
--- /dev/null
+++ b/vulkan/libvulkan/get_proc_addr.cpp.tmpl
@@ -0,0 +1,180 @@
+{{Include "../api/templates/vulkan_common.tmpl"}}
+{{Global "clang-format" (Strings "clang-format" "-style=file")}}
+{{Macro "DefineGlobals" $}}
+{{$ | Macro "get_proc_addr.cpp" | Format (Global "clang-format") | Write "get_proc_addr.cpp"}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+ Entry point
+-------------------------------------------------------------------------------
+*/}}
+{{define "get_proc_addr.cpp"}}
+/*
+ * Copyright 2015 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.
+ */
+¶
+// This file is generated. Do not edit manually!
+// To regenerate: $ apic template ../api/vulkan.api get_proc_addr.cpp.tmpl
+// Requires apic from https://android.googlesource.com/platform/tools/gpu/.
+¶
+#include <algorithm>
+#include <log/log.h>
+#include "loader.h"
+using namespace vulkan;
+¶
+#define UNLIKELY(expr) __builtin_expect((expr), 0)
+¶
+namespace {
+¶
+struct NameProcEntry {
+ const char* name;
+ PFN_vkVoidFunction proc;
+};
+¶
+struct NameOffsetEntry {
+ const char* name;
+ size_t offset;
+};
+¶
+template <typename TEntry, size_t N>
+const TEntry* FindProcEntry(const TEntry(&table)[N], const char* name) {
+ auto entry = std::lower_bound(
+ table, table + N, name,
+ [](const TEntry& e, const char* n) { return strcmp(e.name, n) < 0; });
+ if (entry != (table + N) && strcmp(entry->name, name) == 0)
+ return entry;
+ return nullptr;
+}
+¶
+const NameProcEntry kInstanceProcTbl[] = {«
+ // clang-format off
+ {{range $f := SortBy (AllCommands $) "FunctionName"}}
+ {{if eq (Macro "Vtbl" $f) "Instance"}}
+ {"{{Macro "FunctionName" $f}}", reinterpret_cast<PFN_vkVoidFunction>({{Macro "FunctionName" $f}})},
+ {{end}}
+ {{end}}
+ // clang-format on
+»};
+¶
+const NameProcEntry kDeviceProcTbl[] = {«
+ // clang-format off
+ {{range $f := SortBy (AllCommands $) "FunctionName"}}
+ {{if eq (Macro "Vtbl" $f) "Device"}}
+ {"{{Macro "FunctionName" $f}}", reinterpret_cast<PFN_vkVoidFunction>({{Macro "FunctionName" $f}})},
+ {{end}}
+ {{end}}
+ // clang-format on
+»};
+¶
+const NameOffsetEntry kInstanceOffsetTbl[] = {«
+ // clang-format off
+ {{range $f := SortBy (AllCommands $) "FunctionName"}}
+ {{if eq (Macro "Vtbl" $f) "Instance"}}
+ {"{{Macro "FunctionName" $f}}", offsetof(InstanceVtbl, {{TrimPrefix "vk" (Macro "FunctionName" $f)}})},
+ {{end}}
+ {{end}}
+ // clang-format on
+»};
+¶
+const NameOffsetEntry kDeviceOffsetTbl[] = {«
+ // clang-format off
+ {{range $f := SortBy (AllCommands $) "FunctionName"}}
+ {{if eq (Macro "Vtbl" $f) "Device"}}
+ {"{{Macro "FunctionName" $f}}", offsetof(DeviceVtbl, {{TrimPrefix "vk" (Macro "FunctionName" $f)}})},
+ {{end}}
+ {{end}}
+ // clang-format on
+»};
+¶
+} // namespace
+¶
+namespace vulkan {
+¶
+PFN_vkVoidFunction GetGlobalInstanceProcAddr(const char* name) {
+ if (strcmp(name, "vkGetDeviceProcAddr") == 0)
+ return reinterpret_cast<PFN_vkVoidFunction>(vkGetDeviceProcAddr);
+ const NameProcEntry* entry = FindProcEntry(kInstanceProcTbl, name);
+ return entry ? entry->proc : nullptr;
+}
+¶
+PFN_vkVoidFunction GetGlobalDeviceProcAddr(const char* name) {
+ const NameProcEntry* entry = FindProcEntry(kDeviceProcTbl, name);
+ return entry ? entry->proc : nullptr;
+}
+¶
+PFN_vkVoidFunction GetSpecificInstanceProcAddr(const InstanceVtbl* vtbl,
+ const char* name) {
+ const NameOffsetEntry* entry = FindProcEntry(kInstanceOffsetTbl, name);
+ if (!entry)
+ return nullptr;
+ const unsigned char* base = reinterpret_cast<const unsigned char*>(vtbl);
+ return reinterpret_cast<PFN_vkVoidFunction>(
+ const_cast<unsigned char*>(base) + entry->offset);
+}
+¶
+PFN_vkVoidFunction GetSpecificDeviceProcAddr(const DeviceVtbl* vtbl,
+ const char* name) {
+ const NameOffsetEntry* entry = FindProcEntry(kDeviceOffsetTbl, name);
+ if (!entry)
+ return nullptr;
+ const unsigned char* base = reinterpret_cast<const unsigned char*>(vtbl);
+ return reinterpret_cast<PFN_vkVoidFunction>(
+ const_cast<unsigned char*>(base) + entry->offset);
+}
+¶
+bool LoadInstanceVtbl(VkInstance instance,
+ PFN_vkGetInstanceProcAddr get_proc_addr,
+ InstanceVtbl& vtbl) {«
+ bool success = true;
+ // clang-format off
+ {{range $f := AllCommands $}}
+ {{if eq (Macro "Vtbl" $f) "Instance"}}
+ vtbl.{{TrimPrefix "vk" (Macro "FunctionName" $f)}} = §
+ reinterpret_cast<{{Macro "FunctionPtrName" $f}}>(§
+ get_proc_addr(instance, "{{Macro "FunctionName" $f}}"));
+ if (UNLIKELY(!vtbl.{{TrimPrefix "vk" (Macro "FunctionName" $f)}})) {
+ ALOGE("missing instance proc: %s", "{{Macro "FunctionName" $f}}");
+ success = false;
+ }
+ {{end}}
+ {{end}}
+ // clang-format on
+ return success;
+»}
+¶
+bool LoadDeviceVtbl(VkDevice device,
+ PFN_vkGetDeviceProcAddr get_proc_addr,
+ DeviceVtbl& vtbl) {«
+ bool success = true;
+ // clang-format off
+ {{range $f := AllCommands $}}
+ {{if eq (Macro "Vtbl" $f) "Device"}}
+ vtbl.{{TrimPrefix "vk" (Macro "FunctionName" $f)}} = §
+ reinterpret_cast<{{Macro "FunctionPtrName" $f}}>(§
+ get_proc_addr(device, "{{Macro "FunctionName" $f}}"));
+ if (UNLIKELY(!vtbl.{{TrimPrefix "vk" (Macro "FunctionName" $f)}})) {
+ ALOGE("missing device proc: %s", "{{Macro "FunctionName" $f}}");
+ success = false;
+ }
+ {{end}}
+ {{end}}
+ // clang-format on
+ return success;
+»}
+¶
+} // namespace vulkan
+¶
+{{end}}
diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp
new file mode 100644
index 0000000..a99e90a
--- /dev/null
+++ b/vulkan/libvulkan/loader.cpp
@@ -0,0 +1,532 @@
+// module header
+#include "loader.h"
+// standard C headers
+#include <inttypes.h>
+#include <malloc.h>
+#include <pthread.h>
+#include <string.h>
+// standard C++ headers
+#include <algorithm>
+#include <mutex>
+// platform/library headers
+#include <hardware/hwvulkan.h>
+#include <log/log.h>
+
+using namespace vulkan;
+
+static const uint32_t kMaxPhysicalDevices = 4;
+
+struct VkInstance_T {
+ VkInstance_T(const VkAllocCallbacks* alloc_callbacks)
+ : vtbl(&vtbl_storage), alloc(alloc_callbacks), num_physical_devices(0) {
+ memset(&vtbl_storage, 0, sizeof(vtbl_storage));
+ memset(physical_devices, 0, sizeof(physical_devices));
+ memset(&drv.vtbl, 0, sizeof(drv.vtbl));
+ drv.GetDeviceProcAddr = nullptr;
+ drv.num_physical_devices = 0;
+ }
+
+ InstanceVtbl* vtbl;
+ InstanceVtbl vtbl_storage;
+
+ const VkAllocCallbacks* alloc;
+ uint32_t num_physical_devices;
+ VkPhysicalDevice physical_devices[kMaxPhysicalDevices];
+
+ struct Driver {
+ // Pointers to driver entry points. Used explicitly by the loader; not
+ // set as the dispatch table for any objects.
+ InstanceVtbl vtbl;
+
+ // Pointer to the driver's get_device_proc_addr, must be valid for any
+ // of the driver's physical devices. Not part of the InstanceVtbl since
+ // it's not an Instance/PhysicalDevice function.
+ PFN_vkGetDeviceProcAddr GetDeviceProcAddr;
+
+ // Number of physical devices owned by this driver.
+ uint32_t num_physical_devices;
+ } drv; // may eventually be an array
+};
+
+// -----------------------------------------------------------------------------
+
+namespace {
+
+typedef VkInstance_T Instance;
+
+struct Device {
+ Device(const VkAllocCallbacks* alloc_callbacks) : alloc(alloc_callbacks) {
+ memset(&vtbl_storage, 0, sizeof(vtbl_storage));
+ vtbl_storage.device = this;
+ }
+ DeviceVtbl vtbl_storage;
+ const VkAllocCallbacks* alloc;
+};
+
+// -----------------------------------------------------------------------------
+// Utility Code
+
+inline const InstanceVtbl* GetVtbl(VkPhysicalDevice physicalDevice) {
+ return *reinterpret_cast<InstanceVtbl**>(physicalDevice);
+}
+
+inline const DeviceVtbl* GetVtbl(VkDevice device) {
+ return *reinterpret_cast<DeviceVtbl**>(device);
+}
+
+void* DefaultAlloc(void*, size_t size, size_t alignment, VkSystemAllocType) {
+ return memalign(alignment, size);
+}
+
+void DefaultFree(void*, void* pMem) {
+ free(pMem);
+}
+
+const VkAllocCallbacks kDefaultAllocCallbacks = {
+ .pUserData = nullptr,
+ .pfnAlloc = DefaultAlloc,
+ .pfnFree = DefaultFree,
+};
+
+hwvulkan_device_t* g_hwdevice;
+bool EnsureInitialized() {
+ static std::once_flag once_flag;
+ static const hwvulkan_module_t* module;
+
+ std::call_once(once_flag, []() {
+ int result;
+ result = hw_get_module("vulkan",
+ reinterpret_cast<const hw_module_t**>(&module));
+ if (result != 0) {
+ ALOGE("failed to load vulkan hal: %s (%d)", strerror(-result),
+ result);
+ return;
+ }
+ result = module->common.methods->open(
+ &module->common, HWVULKAN_DEVICE_0,
+ reinterpret_cast<hw_device_t**>(&g_hwdevice));
+ if (result != 0) {
+ ALOGE("failed to open vulkan driver: %s (%d)", strerror(-result),
+ result);
+ module = nullptr;
+ return;
+ }
+ });
+
+ return module != nullptr && g_hwdevice != nullptr;
+}
+
+void DestroyDevice(Device* device) {
+ const VkAllocCallbacks* alloc = device->alloc;
+ device->~Device();
+ alloc->pfnFree(alloc->pUserData, device);
+}
+
+// -----------------------------------------------------------------------------
+// "Bottom" functions. These are called at the end of the instance dispatch
+// chain.
+
+VkResult DestroyInstanceBottom(VkInstance instance) {
+ // These checks allow us to call DestroyInstanceBottom from any error path
+ // in CreateInstanceBottom, before the driver instance is fully initialized.
+ if (instance->drv.vtbl.instance != VK_NULL_HANDLE &&
+ instance->drv.vtbl.DestroyInstance) {
+ instance->drv.vtbl.DestroyInstance(instance->drv.vtbl.instance);
+ }
+ const VkAllocCallbacks* alloc = instance->alloc;
+ instance->~VkInstance_T();
+ alloc->pfnFree(alloc->pUserData, instance);
+ return VK_SUCCESS;
+}
+
+VkResult CreateInstanceBottom(const VkInstanceCreateInfo* create_info,
+ VkInstance* instance_ptr) {
+ Instance* instance = *instance_ptr;
+ VkResult result;
+
+ result =
+ g_hwdevice->CreateInstance(create_info, &instance->drv.vtbl.instance);
+ if (result != VK_SUCCESS) {
+ DestroyInstanceBottom(instance);
+ return result;
+ }
+
+ if (!LoadInstanceVtbl(instance->drv.vtbl.instance,
+ g_hwdevice->GetInstanceProcAddr,
+ instance->drv.vtbl)) {
+ DestroyInstanceBottom(instance);
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ // vkGetDeviceProcAddr has a bootstrapping problem. We require that it be
+ // queryable from the Instance, and that the resulting function work for any
+ // VkDevice created from the instance.
+ instance->drv.GetDeviceProcAddr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
+ g_hwdevice->GetInstanceProcAddr(instance->drv.vtbl.instance,
+ "vkGetDeviceProcAddr"));
+ if (!instance->drv.GetDeviceProcAddr) {
+ ALOGE("missing instance proc: \"%s\"", "vkGetDeviceProcAddr");
+ DestroyInstanceBottom(instance);
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ hwvulkan_dispatch_t* dispatch =
+ reinterpret_cast<hwvulkan_dispatch_t*>(instance->drv.vtbl.instance);
+ if (dispatch->magic == HWVULKAN_DISPATCH_MAGIC) {
+ // Skip setting dispatch->vtbl on the driver instance handle, since we
+ // never intentionally call through it; we go through Instance::drv.vtbl
+ // instead.
+ } else {
+ ALOGE("invalid VkInstance dispatch magic: 0x%" PRIxPTR,
+ dispatch->magic);
+ DestroyInstanceBottom(instance);
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ uint32_t num_physical_devices = 0;
+ result = instance->drv.vtbl.EnumeratePhysicalDevices(
+ instance->drv.vtbl.instance, &num_physical_devices, nullptr);
+ if (result != VK_SUCCESS) {
+ DestroyInstanceBottom(instance);
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ num_physical_devices = std::min(num_physical_devices, kMaxPhysicalDevices);
+ result = instance->drv.vtbl.EnumeratePhysicalDevices(
+ instance->drv.vtbl.instance, &num_physical_devices,
+ instance->physical_devices);
+ if (result != VK_SUCCESS) {
+ DestroyInstanceBottom(instance);
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ for (uint32_t i = 0; i < num_physical_devices; i++) {
+ dispatch = reinterpret_cast<hwvulkan_dispatch_t*>(
+ instance->physical_devices[i]);
+ if (dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
+ ALOGE("invalid VkPhysicalDevice dispatch magic: 0x%" PRIxPTR,
+ dispatch->magic);
+ DestroyInstanceBottom(instance);
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ dispatch->vtbl = instance->vtbl;
+ }
+ instance->drv.num_physical_devices = num_physical_devices;
+
+ instance->num_physical_devices = instance->drv.num_physical_devices;
+ return VK_SUCCESS;
+}
+
+VkResult EnumeratePhysicalDevicesBottom(VkInstance instance,
+ uint32_t* pdev_count,
+ VkPhysicalDevice* pdevs) {
+ uint32_t count = instance->num_physical_devices;
+ if (pdevs) {
+ count = std::min(count, *pdev_count);
+ std::copy(instance->physical_devices,
+ instance->physical_devices + count, pdevs);
+ }
+ *pdev_count = count;
+ return VK_SUCCESS;
+}
+
+VkResult GetPhysicalDeviceFeaturesBottom(VkPhysicalDevice pdev,
+ VkPhysicalDeviceFeatures* features) {
+ return GetVtbl(pdev)
+ ->instance->drv.vtbl.GetPhysicalDeviceFeatures(pdev, features);
+}
+
+VkResult GetPhysicalDeviceFormatPropertiesBottom(
+ VkPhysicalDevice pdev,
+ VkFormat format,
+ VkFormatProperties* properties) {
+ return GetVtbl(pdev)->instance->drv.vtbl.GetPhysicalDeviceFormatProperties(
+ pdev, format, properties);
+}
+
+VkResult GetPhysicalDeviceImageFormatPropertiesBottom(
+ VkPhysicalDevice pdev,
+ VkFormat format,
+ VkImageType type,
+ VkImageTiling tiling,
+ VkImageUsageFlags usage,
+ VkImageFormatProperties* properties) {
+ return GetVtbl(pdev)
+ ->instance->drv.vtbl.GetPhysicalDeviceImageFormatProperties(
+ pdev, format, type, tiling, usage, properties);
+}
+
+VkResult GetPhysicalDeviceLimitsBottom(VkPhysicalDevice pdev,
+ VkPhysicalDeviceLimits* limits) {
+ return GetVtbl(pdev)
+ ->instance->drv.vtbl.GetPhysicalDeviceLimits(pdev, limits);
+}
+
+VkResult GetPhysicalDevicePropertiesBottom(
+ VkPhysicalDevice pdev,
+ VkPhysicalDeviceProperties* properties) {
+ return GetVtbl(pdev)
+ ->instance->drv.vtbl.GetPhysicalDeviceProperties(pdev, properties);
+}
+
+VkResult GetPhysicalDeviceQueueCountBottom(VkPhysicalDevice pdev,
+ uint32_t* count) {
+ return GetVtbl(pdev)
+ ->instance->drv.vtbl.GetPhysicalDeviceQueueCount(pdev, count);
+}
+
+VkResult GetPhysicalDeviceQueuePropertiesBottom(
+ VkPhysicalDevice pdev,
+ uint32_t count,
+ VkPhysicalDeviceQueueProperties* properties) {
+ return GetVtbl(pdev)->instance->drv.vtbl.GetPhysicalDeviceQueueProperties(
+ pdev, count, properties);
+}
+
+VkResult GetPhysicalDeviceMemoryPropertiesBottom(
+ VkPhysicalDevice pdev,
+ VkPhysicalDeviceMemoryProperties* properties) {
+ return GetVtbl(pdev)->instance->drv.vtbl.GetPhysicalDeviceMemoryProperties(
+ pdev, properties);
+}
+
+VkResult CreateDeviceBottom(VkPhysicalDevice pdev,
+ const VkDeviceCreateInfo* create_info,
+ VkDevice* out_device) {
+ const Instance& instance = *static_cast<Instance*>(GetVtbl(pdev)->instance);
+ VkResult result;
+
+ void* mem = instance.alloc->pfnAlloc(instance.alloc->pUserData,
+ sizeof(Device), alignof(Device),
+ VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+ if (!mem)
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ Device* device = new (mem) Device(instance.alloc);
+
+ VkDevice drv_device;
+ result = instance.drv.vtbl.CreateDevice(pdev, create_info, &drv_device);
+ if (result != VK_SUCCESS) {
+ DestroyDevice(device);
+ return result;
+ }
+
+ if (!LoadDeviceVtbl(drv_device, instance.drv.GetDeviceProcAddr,
+ device->vtbl_storage)) {
+ if (device->vtbl_storage.DestroyDevice)
+ device->vtbl_storage.DestroyDevice(drv_device);
+ DestroyDevice(device);
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ hwvulkan_dispatch_t* dispatch =
+ reinterpret_cast<hwvulkan_dispatch_t*>(drv_device);
+ if (dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
+ ALOGE("invalid VkDevice dispatch magic: 0x%" PRIxPTR, dispatch->magic);
+ device->vtbl_storage.DestroyDevice(drv_device);
+ DestroyDevice(device);
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ dispatch->vtbl = &device->vtbl_storage;
+
+ // TODO: insert device layer entry points into device->vtbl_storage here?
+
+ *out_device = drv_device;
+ return VK_SUCCESS;
+}
+
+VkResult GetPhysicalDeviceExtensionPropertiesBottom(
+ VkPhysicalDevice pdev,
+ const char* layer_name,
+ uint32_t* properties_count,
+ VkExtensionProperties* properties) {
+ // TODO: what are we supposed to do with layer_name here?
+ return GetVtbl(pdev)
+ ->instance->drv.vtbl.GetPhysicalDeviceExtensionProperties(
+ pdev, layer_name, properties_count, properties);
+}
+
+VkResult GetPhysicalDeviceLayerPropertiesBottom(VkPhysicalDevice pdev,
+ uint32_t* properties_count,
+ VkLayerProperties* properties) {
+ return GetVtbl(pdev)->instance->drv.vtbl.GetPhysicalDeviceLayerProperties(
+ pdev, properties_count, properties);
+}
+
+VkResult GetPhysicalDeviceSparseImageFormatPropertiesBottom(
+ VkPhysicalDevice pdev,
+ VkFormat format,
+ VkImageType type,
+ uint32_t samples,
+ VkImageUsageFlags usage,
+ VkImageTiling tiling,
+ uint32_t* properties_count,
+ VkSparseImageFormatProperties* properties) {
+ return GetVtbl(pdev)
+ ->instance->drv.vtbl.GetPhysicalDeviceSparseImageFormatProperties(
+ pdev, format, type, samples, usage, tiling, properties_count,
+ properties);
+}
+
+PFN_vkVoidFunction GetInstanceProcAddrBottom(VkInstance, const char*);
+
+const InstanceVtbl kBottomInstanceFunctions = {
+ // clang-format off
+ .instance = nullptr,
+ .CreateInstance = CreateInstanceBottom,
+ .DestroyInstance = DestroyInstanceBottom,
+ .GetInstanceProcAddr = GetInstanceProcAddrBottom,
+ .EnumeratePhysicalDevices = EnumeratePhysicalDevicesBottom,
+ .GetPhysicalDeviceFeatures = GetPhysicalDeviceFeaturesBottom,
+ .GetPhysicalDeviceFormatProperties = GetPhysicalDeviceFormatPropertiesBottom,
+ .GetPhysicalDeviceImageFormatProperties = GetPhysicalDeviceImageFormatPropertiesBottom,
+ .GetPhysicalDeviceLimits = GetPhysicalDeviceLimitsBottom,
+ .GetPhysicalDeviceProperties = GetPhysicalDevicePropertiesBottom,
+ .GetPhysicalDeviceQueueCount = GetPhysicalDeviceQueueCountBottom,
+ .GetPhysicalDeviceQueueProperties = GetPhysicalDeviceQueuePropertiesBottom,
+ .GetPhysicalDeviceMemoryProperties = GetPhysicalDeviceMemoryPropertiesBottom,
+ .CreateDevice = CreateDeviceBottom,
+ .GetPhysicalDeviceExtensionProperties = GetPhysicalDeviceExtensionPropertiesBottom,
+ .GetPhysicalDeviceLayerProperties = GetPhysicalDeviceLayerPropertiesBottom,
+ .GetPhysicalDeviceSparseImageFormatProperties = GetPhysicalDeviceSparseImageFormatPropertiesBottom,
+ // clang-format on
+};
+
+PFN_vkVoidFunction GetInstanceProcAddrBottom(VkInstance, const char* name) {
+ // The bottom GetInstanceProcAddr is only called by the innermost layer,
+ // when there is one, when it initializes its own dispatch table.
+ return GetSpecificInstanceProcAddr(&kBottomInstanceFunctions, name);
+}
+
+} // namespace
+
+// -----------------------------------------------------------------------------
+// Global functions. These are called directly from the loader entry points,
+// without going through a dispatch table.
+
+namespace vulkan {
+
+VkResult GetGlobalExtensionProperties(const char* /*layer_name*/,
+ uint32_t* count,
+ VkExtensionProperties* /*properties*/) {
+ if (!count)
+ return VK_ERROR_INVALID_POINTER;
+ if (!EnsureInitialized())
+ return VK_ERROR_UNAVAILABLE;
+
+ // TODO: not yet implemented
+ ALOGW("vkGetGlobalExtensionProperties not implemented");
+
+ *count = 0;
+ return VK_SUCCESS;
+}
+
+VkResult GetGlobalLayerProperties(uint32_t* count,
+ VkLayerProperties* /*properties*/) {
+ if (!count)
+ return VK_ERROR_INVALID_POINTER;
+ if (!EnsureInitialized())
+ return VK_ERROR_UNAVAILABLE;
+
+ // TODO: not yet implemented
+ ALOGW("vkGetGlobalLayerProperties not implemented");
+
+ *count = 0;
+ return VK_SUCCESS;
+}
+
+VkResult CreateInstance(const VkInstanceCreateInfo* create_info,
+ VkInstance* out_instance) {
+ VkResult result;
+
+ if (!EnsureInitialized())
+ return VK_ERROR_UNAVAILABLE;
+
+ VkInstanceCreateInfo local_create_info = *create_info;
+ if (!local_create_info.pAllocCb)
+ local_create_info.pAllocCb = &kDefaultAllocCallbacks;
+ create_info = &local_create_info;
+
+ void* instance_mem = create_info->pAllocCb->pfnAlloc(
+ create_info->pAllocCb->pUserData, sizeof(Instance), alignof(Instance),
+ VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+ if (!instance_mem)
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ Instance* instance = new (instance_mem) Instance(create_info->pAllocCb);
+
+ instance->vtbl_storage = kBottomInstanceFunctions;
+ instance->vtbl_storage.instance = instance;
+
+ // TODO: Insert enabled layers into instance->dispatch_vtbl here.
+
+ // TODO: We'll want to call CreateInstance through the dispatch table
+ // instead of calling the loader's terminator
+ *out_instance = instance;
+ result = CreateInstanceBottom(create_info, out_instance);
+ if (result <= 0) {
+ // For every layer, including the loader top and bottom layers:
+ // - If a call to the next CreateInstance fails, the layer must clean
+ // up anything it has successfully done so far, and propagate the
+ // error upwards.
+ // - If a layer successfully calls the next layer's CreateInstance, and
+ // afterwards must fail for some reason, it must call the next layer's
+ // DestroyInstance before returning.
+ // - The layer must not call the next layer's DestroyInstance if that
+ // layer's CreateInstance wasn't called, or returned failure.
+
+ // On failure, CreateInstanceBottom frees the instance struct, so it's
+ // already gone at this point. Nothing to do.
+ }
+
+ return result;
+}
+
+PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* name) {
+ if (!instance)
+ return GetGlobalInstanceProcAddr(name);
+ // For special-case functions we always return the loader entry
+ if (strcmp(name, "vkGetInstanceProcAddr") == 0 ||
+ strcmp(name, "vkGetDeviceProcAddr") == 0) {
+ return GetGlobalInstanceProcAddr(name);
+ }
+ return GetSpecificInstanceProcAddr(instance->vtbl, name);
+}
+
+PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* name) {
+ if (!device)
+ return GetGlobalDeviceProcAddr(name);
+ // For special-case functions we always return the loader entry
+ if (strcmp(name, "vkGetDeviceQueue") == 0 ||
+ strcmp(name, "vkDestroyDevice") == 0) {
+ return GetGlobalDeviceProcAddr(name);
+ }
+ return GetSpecificDeviceProcAddr(GetVtbl(device), name);
+}
+
+VkResult GetDeviceQueue(VkDevice drv_device,
+ uint32_t family,
+ uint32_t index,
+ VkQueue* out_queue) {
+ VkResult result;
+ VkQueue queue;
+ const DeviceVtbl* vtbl = GetVtbl(drv_device);
+ result = vtbl->GetDeviceQueue(drv_device, family, index, &queue);
+ if (result != VK_SUCCESS)
+ return result;
+ hwvulkan_dispatch_t* dispatch =
+ reinterpret_cast<hwvulkan_dispatch_t*>(queue);
+ if (dispatch->magic != HWVULKAN_DISPATCH_MAGIC && dispatch->vtbl != &vtbl) {
+ ALOGE("invalid VkQueue dispatch magic: 0x%" PRIxPTR, dispatch->magic);
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ dispatch->vtbl = vtbl;
+ *out_queue = queue;
+ return VK_SUCCESS;
+}
+
+VkResult DestroyDevice(VkDevice drv_device) {
+ const DeviceVtbl* vtbl = GetVtbl(drv_device);
+ Device* device = static_cast<Device*>(vtbl->device);
+ vtbl->DestroyDevice(drv_device);
+ DestroyDevice(device);
+ return VK_SUCCESS;
+}
+
+} // namespace vulkan
diff --git a/vulkan/libvulkan/loader.h b/vulkan/libvulkan/loader.h
new file mode 100644
index 0000000..1f6a1d4
--- /dev/null
+++ b/vulkan/libvulkan/loader.h
@@ -0,0 +1,211 @@
+#ifndef LIBVULKAN_LOADER_H
+#define LIBVULKAN_LOADER_H 1
+
+#define VK_PROTOTYPES
+#include <vulkan/vulkan.h>
+
+namespace vulkan {
+
+struct InstanceVtbl {
+ // clang-format off
+ VkInstance instance;
+
+ PFN_vkCreateInstance CreateInstance;
+ PFN_vkDestroyInstance DestroyInstance;
+ PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
+ PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices;
+
+ PFN_vkGetPhysicalDeviceFeatures GetPhysicalDeviceFeatures;
+ PFN_vkGetPhysicalDeviceFormatProperties GetPhysicalDeviceFormatProperties;
+ PFN_vkGetPhysicalDeviceImageFormatProperties GetPhysicalDeviceImageFormatProperties;
+ PFN_vkGetPhysicalDeviceLimits GetPhysicalDeviceLimits;
+ PFN_vkGetPhysicalDeviceProperties GetPhysicalDeviceProperties;
+ PFN_vkGetPhysicalDeviceQueueCount GetPhysicalDeviceQueueCount;
+ PFN_vkGetPhysicalDeviceQueueProperties GetPhysicalDeviceQueueProperties;
+ PFN_vkGetPhysicalDeviceMemoryProperties GetPhysicalDeviceMemoryProperties;
+ PFN_vkCreateDevice CreateDevice;
+ PFN_vkGetPhysicalDeviceExtensionProperties GetPhysicalDeviceExtensionProperties;
+ PFN_vkGetPhysicalDeviceLayerProperties GetPhysicalDeviceLayerProperties;
+ PFN_vkGetPhysicalDeviceSparseImageFormatProperties GetPhysicalDeviceSparseImageFormatProperties;
+ // clang-format on
+};
+
+struct DeviceVtbl {
+ void* device;
+
+ PFN_vkGetDeviceProcAddr GetDeviceProcAddr;
+ PFN_vkDestroyDevice DestroyDevice;
+ PFN_vkGetDeviceQueue GetDeviceQueue;
+ PFN_vkDeviceWaitIdle DeviceWaitIdle;
+ PFN_vkAllocMemory AllocMemory;
+ PFN_vkFreeMemory FreeMemory;
+ PFN_vkMapMemory MapMemory;
+ PFN_vkUnmapMemory UnmapMemory;
+ PFN_vkFlushMappedMemoryRanges FlushMappedMemoryRanges;
+ PFN_vkInvalidateMappedMemoryRanges InvalidateMappedMemoryRanges;
+ PFN_vkGetDeviceMemoryCommitment GetDeviceMemoryCommitment;
+ PFN_vkBindBufferMemory BindBufferMemory;
+ PFN_vkBindImageMemory BindImageMemory;
+ PFN_vkGetBufferMemoryRequirements GetBufferMemoryRequirements;
+ PFN_vkGetImageMemoryRequirements GetImageMemoryRequirements;
+ PFN_vkGetImageSparseMemoryRequirements GetImageSparseMemoryRequirements;
+ PFN_vkCreateFence CreateFence;
+ PFN_vkDestroyFence DestroyFence;
+ PFN_vkResetFences ResetFences;
+ PFN_vkGetFenceStatus GetFenceStatus;
+ PFN_vkWaitForFences WaitForFences;
+ PFN_vkCreateSemaphore CreateSemaphore;
+ PFN_vkDestroySemaphore DestroySemaphore;
+ PFN_vkCreateEvent CreateEvent;
+ PFN_vkDestroyEvent DestroyEvent;
+ PFN_vkGetEventStatus GetEventStatus;
+ PFN_vkSetEvent SetEvent;
+ PFN_vkResetEvent ResetEvent;
+ PFN_vkCreateQueryPool CreateQueryPool;
+ PFN_vkDestroyQueryPool DestroyQueryPool;
+ PFN_vkGetQueryPoolResults GetQueryPoolResults;
+ PFN_vkCreateBuffer CreateBuffer;
+ PFN_vkDestroyBuffer DestroyBuffer;
+ PFN_vkCreateBufferView CreateBufferView;
+ PFN_vkDestroyBufferView DestroyBufferView;
+ PFN_vkCreateImage CreateImage;
+ PFN_vkDestroyImage DestroyImage;
+ PFN_vkGetImageSubresourceLayout GetImageSubresourceLayout;
+ PFN_vkCreateImageView CreateImageView;
+ PFN_vkDestroyImageView DestroyImageView;
+ PFN_vkCreateAttachmentView CreateAttachmentView;
+ PFN_vkDestroyAttachmentView DestroyAttachmentView;
+ PFN_vkCreateShaderModule CreateShaderModule;
+ PFN_vkDestroyShaderModule DestroyShaderModule;
+ PFN_vkCreateShader CreateShader;
+ PFN_vkDestroyShader DestroyShader;
+ PFN_vkCreatePipelineCache CreatePipelineCache;
+ PFN_vkDestroyPipelineCache DestroyPipelineCache;
+ PFN_vkGetPipelineCacheSize GetPipelineCacheSize;
+ PFN_vkGetPipelineCacheData GetPipelineCacheData;
+ PFN_vkMergePipelineCaches MergePipelineCaches;
+ PFN_vkCreateGraphicsPipelines CreateGraphicsPipelines;
+ PFN_vkCreateComputePipelines CreateComputePipelines;
+ PFN_vkDestroyPipeline DestroyPipeline;
+ PFN_vkCreatePipelineLayout CreatePipelineLayout;
+ PFN_vkDestroyPipelineLayout DestroyPipelineLayout;
+ PFN_vkCreateSampler CreateSampler;
+ PFN_vkDestroySampler DestroySampler;
+ PFN_vkCreateDescriptorSetLayout CreateDescriptorSetLayout;
+ PFN_vkDestroyDescriptorSetLayout DestroyDescriptorSetLayout;
+ PFN_vkCreateDescriptorPool CreateDescriptorPool;
+ PFN_vkDestroyDescriptorPool DestroyDescriptorPool;
+ PFN_vkResetDescriptorPool ResetDescriptorPool;
+ PFN_vkAllocDescriptorSets AllocDescriptorSets;
+ PFN_vkFreeDescriptorSets FreeDescriptorSets;
+ PFN_vkUpdateDescriptorSets UpdateDescriptorSets;
+ PFN_vkCreateDynamicViewportState CreateDynamicViewportState;
+ PFN_vkDestroyDynamicViewportState DestroyDynamicViewportState;
+ PFN_vkCreateDynamicRasterState CreateDynamicRasterState;
+ PFN_vkDestroyDynamicRasterState DestroyDynamicRasterState;
+ PFN_vkCreateDynamicColorBlendState CreateDynamicColorBlendState;
+ PFN_vkDestroyDynamicColorBlendState DestroyDynamicColorBlendState;
+ PFN_vkCreateDynamicDepthStencilState CreateDynamicDepthStencilState;
+ PFN_vkDestroyDynamicDepthStencilState DestroyDynamicDepthStencilState;
+ PFN_vkCreateFramebuffer CreateFramebuffer;
+ PFN_vkDestroyFramebuffer DestroyFramebuffer;
+ PFN_vkCreateRenderPass CreateRenderPass;
+ PFN_vkDestroyRenderPass DestroyRenderPass;
+ PFN_vkGetRenderAreaGranularity GetRenderAreaGranularity;
+ PFN_vkCreateCommandPool CreateCommandPool;
+ PFN_vkDestroyCommandPool DestroyCommandPool;
+ PFN_vkResetCommandPool ResetCommandPool;
+ PFN_vkCreateCommandBuffer CreateCommandBuffer;
+ PFN_vkDestroyCommandBuffer DestroyCommandBuffer;
+
+ PFN_vkQueueSubmit QueueSubmit;
+ PFN_vkQueueWaitIdle QueueWaitIdle;
+ PFN_vkQueueBindSparseBufferMemory QueueBindSparseBufferMemory;
+ PFN_vkQueueBindSparseImageOpaqueMemory QueueBindSparseImageOpaqueMemory;
+ PFN_vkQueueBindSparseImageMemory QueueBindSparseImageMemory;
+ PFN_vkQueueSignalSemaphore QueueSignalSemaphore;
+ PFN_vkQueueWaitSemaphore QueueWaitSemaphore;
+
+ PFN_vkBeginCommandBuffer BeginCommandBuffer;
+ PFN_vkEndCommandBuffer EndCommandBuffer;
+ PFN_vkResetCommandBuffer ResetCommandBuffer;
+ PFN_vkCmdBindPipeline CmdBindPipeline;
+ PFN_vkCmdBindDynamicViewportState CmdBindDynamicViewportState;
+ PFN_vkCmdBindDynamicRasterState CmdBindDynamicRasterState;
+ PFN_vkCmdBindDynamicColorBlendState CmdBindDynamicColorBlendState;
+ PFN_vkCmdBindDynamicDepthStencilState CmdBindDynamicDepthStencilState;
+ PFN_vkCmdBindDescriptorSets CmdBindDescriptorSets;
+ PFN_vkCmdBindIndexBuffer CmdBindIndexBuffer;
+ PFN_vkCmdBindVertexBuffers CmdBindVertexBuffers;
+ PFN_vkCmdDraw CmdDraw;
+ PFN_vkCmdDrawIndexed CmdDrawIndexed;
+ PFN_vkCmdDrawIndirect CmdDrawIndirect;
+ PFN_vkCmdDrawIndexedIndirect CmdDrawIndexedIndirect;
+ PFN_vkCmdDispatch CmdDispatch;
+ PFN_vkCmdDispatchIndirect CmdDispatchIndirect;
+ PFN_vkCmdCopyBuffer CmdCopyBuffer;
+ PFN_vkCmdCopyImage CmdCopyImage;
+ PFN_vkCmdBlitImage CmdBlitImage;
+ PFN_vkCmdCopyBufferToImage CmdCopyBufferToImage;
+ PFN_vkCmdCopyImageToBuffer CmdCopyImageToBuffer;
+ PFN_vkCmdUpdateBuffer CmdUpdateBuffer;
+ PFN_vkCmdFillBuffer CmdFillBuffer;
+ PFN_vkCmdClearColorImage CmdClearColorImage;
+ PFN_vkCmdClearDepthStencilImage CmdClearDepthStencilImage;
+ PFN_vkCmdClearColorAttachment CmdClearColorAttachment;
+ PFN_vkCmdClearDepthStencilAttachment CmdClearDepthStencilAttachment;
+ PFN_vkCmdResolveImage CmdResolveImage;
+ PFN_vkCmdSetEvent CmdSetEvent;
+ PFN_vkCmdResetEvent CmdResetEvent;
+ PFN_vkCmdWaitEvents CmdWaitEvents;
+ PFN_vkCmdPipelineBarrier CmdPipelineBarrier;
+ PFN_vkCmdBeginQuery CmdBeginQuery;
+ PFN_vkCmdEndQuery CmdEndQuery;
+ PFN_vkCmdResetQueryPool CmdResetQueryPool;
+ PFN_vkCmdWriteTimestamp CmdWriteTimestamp;
+ PFN_vkCmdCopyQueryPoolResults CmdCopyQueryPoolResults;
+ PFN_vkCmdPushConstants CmdPushConstants;
+ PFN_vkCmdBeginRenderPass CmdBeginRenderPass;
+ PFN_vkCmdNextSubpass CmdNextSubpass;
+ PFN_vkCmdEndRenderPass CmdEndRenderPass;
+ PFN_vkCmdExecuteCommands CmdExecuteCommands;
+};
+
+// -----------------------------------------------------------------------------
+// loader.cpp
+
+VkResult GetGlobalExtensionProperties(const char* layer_name,
+ uint32_t* count,
+ VkExtensionProperties* properties);
+VkResult GetGlobalLayerProperties(uint32_t* count,
+ VkLayerProperties* properties);
+VkResult CreateInstance(const VkInstanceCreateInfo* create_info,
+ VkInstance* instance);
+PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* name);
+PFN_vkVoidFunction GetDeviceProcAddr(VkDevice drv_device, const char* name);
+VkResult GetDeviceQueue(VkDevice drv_device,
+ uint32_t family,
+ uint32_t index,
+ VkQueue* out_queue);
+VkResult DestroyDevice(VkDevice drv_device);
+
+// -----------------------------------------------------------------------------
+// get_proc_addr.cpp
+
+PFN_vkVoidFunction GetGlobalInstanceProcAddr(const char* name);
+PFN_vkVoidFunction GetGlobalDeviceProcAddr(const char* name);
+PFN_vkVoidFunction GetSpecificInstanceProcAddr(const InstanceVtbl* vtbl,
+ const char* name);
+PFN_vkVoidFunction GetSpecificDeviceProcAddr(const DeviceVtbl* vtbl,
+ const char* name);
+
+bool LoadInstanceVtbl(VkInstance instance,
+ PFN_vkGetInstanceProcAddr get_proc_addr,
+ InstanceVtbl& vtbl);
+bool LoadDeviceVtbl(VkDevice device,
+ PFN_vkGetDeviceProcAddr get_proc_addr,
+ DeviceVtbl& vtbl);
+
+} // namespace vulkan
+
+#endif // LIBVULKAN_LOADER_H