Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc5e2765 authored by Chia-I Wu's avatar Chia-I Wu
Browse files

vulkan: rework DriverDispatchTable

Generate {Instance,Device}DriverTable from code-generator.tmpl to replace
dispatch.tmpl entirely.  The new code avoids initializing
VK_ANDROID_native_buffer entries when the extension is not enabled.  The
separation of instance and device driver tables also allows us to
initialize the device driver table with vkGetDeviceProcAddr, which is
expected to return more efficient function pointers on properly
implemented HALs.

CreateInstance_Bottom always has a potential resource leak when the
HAL-created instance does not contain HWVULKAN_DISPATCH_MAGIC.
CreateDevice_Bottom now has the same issue.  Both of them will be fixed in
following commits.

Change-Id: If7800ef23098121f1fff643a2c5224c2c9be0711
parent eb7db124
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -42,7 +42,6 @@ LOCAL_SRC_FILES := \
	api.cpp \
	api_gen.cpp \
	debug_report.cpp \
	dispatch_gen.cpp \
	driver.cpp \
	driver_gen.cpp \
	layers_extensions.cpp \
+166 −12
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ struct InstanceDispatchTable {
  // clang-format off
  {{range $f := AllCommands $}}
    {{if (Macro "api.IsInstanceDispatchTableEntry" $f)}}
      {{Macro "C++.DeclareDispatchTableEntry" $f}};
      {{Macro "C++.DeclareTableEntry" $f}};
    {{end}}
  {{end}}
  // clang-format on
@@ -56,7 +56,7 @@ struct DeviceDispatchTable {
  // clang-format off
  {{range $f := AllCommands $}}
    {{if (Macro "api.IsDeviceDispatchTableEntry" $f)}}
      {{Macro "C++.DeclareDispatchTableEntry" $f}};
      {{Macro "C++.DeclareTableEntry" $f}};
    {{end}}
  {{end}}
  // clang-format on
@@ -91,7 +91,9 @@ bool InitDispatchTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc);
namespace vulkan {«
namespace api {«

{{Macro "C++.DefineInitProcMacros" "dispatch"}}
{{Macro "C++.DefineInitProcMacro" "dispatch"}}

{{Macro "api.C++.DefineInitProcExtMacro"}}

bool InitDispatchTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc) {
    auto& data = GetData(instance);
@@ -169,9 +171,32 @@ namespace driver {«

{{Macro "driver.C++.DefineProcHookType"}}

struct InstanceDriverTable {
  // clang-format off
  {{range $f := AllCommands $}}
    {{if (Macro "driver.IsInstanceDriverTableEntry" $f)}}
      {{Macro "C++.DeclareTableEntry" $f}};
    {{end}}
  {{end}}
  // clang-format on
};

struct DeviceDriverTable {
  // clang-format off
  {{range $f := AllCommands $}}
    {{if (Macro "driver.IsDeviceDriverTableEntry" $f)}}
      {{Macro "C++.DeclareTableEntry" $f}};
    {{end}}
  {{end}}
  // clang-format on
};

const ProcHook* GetProcHook(const char* name);
ProcHook::Extension GetProcHookExtension(const char* name);

bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc);
bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc);

»} // namespace driver
»} // namespace vulkan

@@ -245,6 +270,42 @@ ProcHook::Extension GetProcHookExtension(const char* name) {
  return ProcHook::EXTENSION_UNKNOWN;
}

{{Macro "C++.DefineInitProcMacro" "driver"}}

{{Macro "driver.C++.DefineInitProcExtMacro"}}

bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc)
{
    auto& data = GetData(instance);
    bool success = true;

    // clang-format off
    {{range $f := AllCommands $}}
      {{if (Macro "driver.IsInstanceDriverTableEntry" $f)}}
        {{Macro "C++.InitProc" $f}}
      {{end}}
    {{end}}
    // clang-format on

    return success;
}

bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc)
{
    auto& data = GetData(dev);
    bool success = true;

    // clang-format off
    {{range $f := AllCommands $}}
      {{if (Macro "driver.IsDeviceDriverTableEntry" $f)}}
        {{Macro "C++.InitProc" $f}}
      {{end}}
    {{end}}
    // clang-format on

    return success;
}

»} // namespace driver
»} // namespace vulkan

@@ -254,10 +315,10 @@ ProcHook::Extension GetProcHookExtension(const char* name) {

{{/*
------------------------------------------------------------------------------
  Emits a declaration of a dispatch table entry.
  Emits a declaration of a dispatch/driver table entry.
------------------------------------------------------------------------------
*/}}
{{define "C++.DeclareDispatchTableEntry"}}
{{define "C++.DeclareTableEntry"}}
  {{AssertType $ "Function"}}

  {{Macro "FunctionPtrName" $}} {{Macro "BaseName" $}}
@@ -266,10 +327,10 @@ ProcHook::Extension GetProcHookExtension(const char* name) {

{{/*
-------------------------------------------------------------------------------
  Emits macros to help initialize dispatch tables.
  Emits INIT_PROC macro.
-------------------------------------------------------------------------------
*/}}
{{define "C++.DefineInitProcMacros"}}
{{define "C++.DefineInitProcMacro"}}
  #define UNLIKELY(expr) __builtin_expect((expr), 0)

  #define INIT_PROC(obj, proc) do {                             \
@@ -280,11 +341,6 @@ ProcHook::Extension GetProcHookExtension(const char* name) {
          success = false;                                      \
      }                                                         \
  } while(0)

  // TODO do we want to point to a stub or nullptr when ext is not enabled?
  #define INIT_PROC_EXT(ext, obj, proc) do {                    \
      INIT_PROC(obj, proc);                                     \
  } while(0)
{{end}}


@@ -367,6 +423,19 @@ ProcHook::Extension GetProcHookExtension(const char* name) {
{{end}}


{{/*
-------------------------------------------------------------------------------
  Emits INIT_PROC_EXT macro for vulkan::api.
-------------------------------------------------------------------------------
*/}}
{{define "api.C++.DefineInitProcExtMacro"}}
  // TODO do we want to point to a stub or nullptr when ext is not enabled?
  #define INIT_PROC_EXT(ext, obj, proc) do {                    \
      INIT_PROC(obj, proc);                                     \
  } while(0)
{{end}}


{{/*
------------------------------------------------------------------------------
  Emits code for vkGetInstanceProcAddr for function interception.
@@ -612,6 +681,19 @@ VK_KHR_swapchain
{{end}}


{{/*
-------------------------------------------------------------------------------
  Emits INIT_PROC_EXT macro for vulkan::driver.
-------------------------------------------------------------------------------
*/}}
{{define "driver.C++.DefineInitProcExtMacro"}}
  #define INIT_PROC_EXT(ext, obj, proc) do {                    \
      if (data.hal_extensions[ProcHook::ext])           \
        INIT_PROC(obj, proc);                                   \
  } while(0)
{{end}}


{{/*
-------------------------------------------------------------------------------
  Emits definitions of stub functions for ProcHook.
@@ -762,6 +844,78 @@ VK_KHR_swapchain
{{end}}


{{/*
-------------------------------------------------------------------------------
  Emits true if a function is needed by vulkan::driver.
-------------------------------------------------------------------------------
*/}}
{{define "driver.IsDriverTableEntry"}}
  {{AssertType $ "Function"}}

  {{if (Macro "IsFunctionSupported" $)}}
    {{/* Create functions of dispatchable objects */}}
    {{     if eq $.Name "vkCreateDevice"}}true
    {{else if eq $.Name "vkGetDeviceQueue"}}true
    {{else if eq $.Name "vkAllocateCommandBuffers"}}true

    {{/* Destroy functions of dispatchable objects */}}
    {{else if eq $.Name "vkDestroyInstance"}}true
    {{else if eq $.Name "vkDestroyDevice"}}true

    {{/* Enumeration of extensions */}}
    {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true

    {{/* We cache physical devices in loader.cpp */}}
    {{else if eq $.Name "vkEnumeratePhysicalDevices"}}true

    {{else if eq $.Name "vkGetInstanceProcAddr"}}true
    {{else if eq $.Name "vkGetDeviceProcAddr"}}true

    {{/* VK_KHR_swapchain->VK_ANDROID_native_buffer translation */}}
    {{else if eq $.Name "vkCreateImage"}}true
    {{else if eq $.Name "vkDestroyImage"}}true

    {{end}}

    {{$ext := GetAnnotation $ "extension"}}
    {{if $ext}}
      {{$ext_name := index $ext.Arguments 0}}
      {{     if eq $ext_name "VK_ANDROID_native_buffer"}}true
      {{else if eq $ext_name "VK_EXT_debug_report"}}true
      {{end}}
    {{end}}
  {{end}}
{{end}}


{{/*
------------------------------------------------------------------------------
  Emits true if an instance-dispatched function is needed by vulkan::driver.
------------------------------------------------------------------------------
*/}}
{{define "driver.IsInstanceDriverTableEntry"}}
  {{AssertType $ "Function"}}

  {{if and (Macro "driver.IsDriverTableEntry" $) (Macro "IsInstanceDispatched" $)}}
    true
  {{end}}
{{end}}


{{/*
------------------------------------------------------------------------------
  Emits true if a device-dispatched function is needed by vulkan::driver.
------------------------------------------------------------------------------
*/}}
{{define "driver.IsDeviceDriverTableEntry"}}
  {{AssertType $ "Function"}}

  {{if and (Macro "driver.IsDriverTableEntry" $) (Macro "IsDeviceDispatched" $)}}
    true
  {{end}}
{{end}}


{{/*
-------------------------------------------------------------------------------
  Emits a function/extension name without the "vk"/"VK_" prefix.

vulkan/libvulkan/dispatch.tmpl

deleted100644 → 0
+0 −326
Original line number Diff line number Diff line
{{/*
 * 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.
 */}}

{{Include "../api/templates/vulkan_common.tmpl"}}
{{Global "clang-format" (Strings "clang-format" "-style=file")}}
{{Macro "DefineGlobals" $}}
{{$ | Macro "dispatch_gen.h"   | Format (Global "clang-format") | Write "dispatch_gen.h"  }}
{{$ | Macro "dispatch_gen.cpp" | Format (Global "clang-format") | Write "dispatch_gen.cpp"}}

{{/*
-------------------------------------------------------------------------------
  dispatch_gen.h
-------------------------------------------------------------------------------
*/}}
{{define "dispatch_gen.h"}}
/*
•* 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.
•*/

// WARNING: This file is generated. See ../README.md for instructions.

#include <vulkan/vk_android_native_buffer.h>
#include <vulkan/vulkan.h>

namespace vulkan {

struct DriverDispatchTable {«
  // clang-format off
  {{range $f := AllCommands $}}
    {{if (Macro "IsInstanceDispatched" $f)}}
      {{if not (Macro "IsLoaderFunction" $f)}}
        {{Macro "FunctionPtrName" $f}} {{Macro "BaseName" $f}};
      {{end}}
    {{end}}
  {{end}}

    PFN_vkGetDeviceProcAddr GetDeviceProcAddr;

    PFN_vkDestroyDevice DestroyDevice;
    PFN_vkGetDeviceQueue GetDeviceQueue;
    PFN_vkAllocateCommandBuffers AllocateCommandBuffers;

    {{/* TODO(jessehall): Needed by swapchain code. Figure out a better way of
         handling this that avoids the special case. Probably should rework
         things so the driver dispatch table has all driver functions. Probably
         need separate instance- and device-level copies, fill in all device-
         dispatched functions in the device-level copies only, and change
         GetDeviceProcAddr_Bottom to look in the already-loaded driver
         dispatch table rather than forwarding to the driver's
         vkGetDeviceProcAddr. */}}
    PFN_vkCreateImage CreateImage;
    PFN_vkDestroyImage DestroyImage;

    PFN_vkGetSwapchainGrallocUsageANDROID GetSwapchainGrallocUsageANDROID;
    PFN_vkAcquireImageANDROID AcquireImageANDROID;
    PFN_vkQueueSignalReleaseImageANDROID QueueSignalReleaseImageANDROID;
  // clang-format on
»};

} // namespace vulkan
¶{{end}}


{{/*
-------------------------------------------------------------------------------
  dispatch_gen.cpp
-------------------------------------------------------------------------------
*/}}
{{define "dispatch_gen.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.
•*/

// WARNING: This file is generated. See ../README.md for instructions.

#include <log/log.h>
#include <algorithm>
#include "loader.h"

#define UNLIKELY(expr) __builtin_expect((expr), 0)

using namespace vulkan;

namespace vulkan {

bool LoadDriverDispatchTable(VkInstance instance,
                             PFN_vkGetInstanceProcAddr get_proc_addr,
                             const InstanceExtensionSet& extensions,
                             DriverDispatchTable& dispatch) {«
    bool success = true;
    // clang-format off
  {{range $f := AllCommands $}}
    {{if (Macro "IsInstanceDispatched" $f)}}
      {{if not (Macro "IsLoaderFunction" $f)}}
        {{$ext := GetAnnotation $f "extension"}}
          {{if $ext}}
    if (extensions[{{Macro "ExtensionConstant" $ext}}]) {
          {{end}}
        dispatch.{{Macro "BaseName" $f}} = §
            reinterpret_cast<{{Macro "FunctionPtrName" $f}}>(§
                get_proc_addr(instance, "{{$f.Name}}"));
        if (UNLIKELY(!dispatch.{{Macro "BaseName" $f}})) {
            ALOGE("missing driver proc: %s", "{{$f.Name}}");
            success = false;
        }
        {{if $ext}}
    }
        {{end}}
      {{end}}
    {{end}}
  {{end}}
    dispatch.GetDeviceProcAddr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(get_proc_addr(instance, "vkGetDeviceProcAddr"));
    if (UNLIKELY(!dispatch.GetDeviceProcAddr)) {
        ALOGE("missing driver proc: %s", "vkGetDeviceProcAddr");
        success = false;
    }
    dispatch.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(get_proc_addr(instance, "vkDestroyDevice"));
    if (UNLIKELY(!dispatch.DestroyDevice)) {
        ALOGE("missing driver proc: %s", "vkDestroyDevice");
        success = false;
    }
    dispatch.GetDeviceQueue = reinterpret_cast<PFN_vkGetDeviceQueue>(get_proc_addr(instance, "vkGetDeviceQueue"));
    if (UNLIKELY(!dispatch.GetDeviceQueue)) {
        ALOGE("missing driver proc: %s", "vkGetDeviceQueue");
        success = false;
    }
    dispatch.AllocateCommandBuffers = reinterpret_cast<PFN_vkAllocateCommandBuffers>(get_proc_addr(instance, "vkAllocateCommandBuffers"));
    if (UNLIKELY(!dispatch.AllocateCommandBuffers)) {
        ALOGE("missing driver proc: %s", "vkAllocateCommandBuffers");
        success = false;
    }
    dispatch.CreateImage = reinterpret_cast<PFN_vkCreateImage>(get_proc_addr(instance, "vkCreateImage"));
    if (UNLIKELY(!dispatch.CreateImage)) {
        ALOGE("missing driver proc: %s", "vkCreateImage");
        success = false;
    }
    dispatch.DestroyImage = reinterpret_cast<PFN_vkDestroyImage>(get_proc_addr(instance, "vkDestroyImage"));
    if (UNLIKELY(!dispatch.DestroyImage)) {
        ALOGE("missing driver proc: %s", "vkDestroyImage");
        success = false;
    }
    dispatch.GetSwapchainGrallocUsageANDROID = reinterpret_cast<PFN_vkGetSwapchainGrallocUsageANDROID>(get_proc_addr(instance, "vkGetSwapchainGrallocUsageANDROID"));
    if (UNLIKELY(!dispatch.GetSwapchainGrallocUsageANDROID)) {
        ALOGE("missing driver proc: %s", "vkGetSwapchainGrallocUsageANDROID");
        success = false;
    }
    dispatch.AcquireImageANDROID = reinterpret_cast<PFN_vkAcquireImageANDROID>(get_proc_addr(instance, "vkAcquireImageANDROID"));
    if (UNLIKELY(!dispatch.AcquireImageANDROID)) {
        ALOGE("missing driver proc: %s", "vkAcquireImageANDROID");
        success = false;
    }
    dispatch.QueueSignalReleaseImageANDROID = reinterpret_cast<PFN_vkQueueSignalReleaseImageANDROID>(get_proc_addr(instance, "vkQueueSignalReleaseImageANDROID"));
    if (UNLIKELY(!dispatch.QueueSignalReleaseImageANDROID)) {
        ALOGE("missing driver proc: %s", "vkQueueSignalReleaseImageANDROID");
        success = false;
    }
    // clang-format on
    return success;
»}

} // namespace vulkan
¶{{end}}


{{/*
-------------------------------------------------------------------------------
  Map an extension name to InstanceExtension or DeviceExtension enum value
-------------------------------------------------------------------------------
*/}}
{{define "ExtensionConstant"}}
  {{$name := index $.Arguments 0}}
  {{     if (eq $name "VK_KHR_surface")}}kKHR_surface
  {{else if (eq $name "VK_KHR_android_surface")}}kKHR_android_surface
  {{else if (eq $name "VK_EXT_debug_report")}}kEXT_debug_report
  {{end}}
{{end}}


{{/*
-------------------------------------------------------------------------------
  Emits a function name without the "vk" prefix.
-------------------------------------------------------------------------------
*/}}
{{define "BaseName"}}
  {{AssertType $ "Function"}}
  {{TrimPrefix "vk" $.Name}}
{{end}}


{{/*
------------------------------------------------------------------------------
  Emit "true" for supported functions that undergo table dispatch. Only global
  functions and functions handled in the loader top without calling into
  lower layers are not dispatched.
------------------------------------------------------------------------------
*/}}
{{define "IsInstanceDispatched"}}
  {{AssertType $ "Function"}}
  {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Instance")}}
    {{if and (ne $.Name "vkEnumerateDeviceLayerProperties") (ne $.Name "vkGetInstanceProcAddr")}}true{{end}}
  {{end}}
{{end}}


{{/*
------------------------------------------------------------------------------
  Emit "true" if a function is core or from a supportable extension.
------------------------------------------------------------------------------
*/}}
{{define "IsFunctionSupported"}}
  {{AssertType $ "Function"}}
  {{if not (GetAnnotation $ "pfn")}}
    {{$ext := GetAnnotation $ "extension"}}
    {{if not $ext}}true
    {{else if not (Macro "IsExtensionBlacklisted" $ext)}}true
    {{end}}
  {{end}}
{{end}}


{{/*
------------------------------------------------------------------------------
  Reports whether an extension function is implemented entirely by the loader,
  and not implemented by drivers.
------------------------------------------------------------------------------
*/}}
{{define "IsLoaderFunction"}}
  {{AssertType $ "Function"}}

  {{$ext := GetAnnotation $ "extension"}}
  {{if $ext}}
    {{Macro "IsLoaderExtension" $ext}}
  {{end}}
{{end}}


{{/*
-------------------------------------------------------------------------------
  Emit "true" if the loader has a bottom-level implementation for the function
  which terminates the dispatch chain.
-------------------------------------------------------------------------------
*/}}
{{define "HasLoaderBottomImpl"}}
  {{AssertType $ "Function"}}

  {{if (Macro "IsFunctionSupported" $)}}
    {{     if (eq (Macro "Vtbl" $) "Instance")}}true
    {{else if (Macro "IsLoaderFunction" $)}}true
    {{else if (eq $.Name "vkCreateInstance")}}true
    {{else if (eq $.Name "vkGetDeviceProcAddr")}}true
    {{else if (eq $.Name "vkDestroyDevice")}}true
    {{else if (eq $.Name "vkGetDeviceQueue")}}true
    {{else if (eq $.Name "vkAllocateCommandBuffers")}}true
    {{end}}
  {{end}}
{{end}}


{{/*
------------------------------------------------------------------------------
  Emit "true" if an extension is unsupportable on Android.
------------------------------------------------------------------------------
*/}}
{{define "IsExtensionBlacklisted"}}
  {{$ext := index $.Arguments 0}}
  {{     if eq $ext "VK_KHR_display"}}true
  {{else if eq $ext "VK_KHR_display_swapchain"}}true
  {{else if eq $ext "VK_KHR_xlib_surface"}}true
  {{else if eq $ext "VK_KHR_xcb_surface"}}true
  {{else if eq $ext "VK_KHR_wayland_surface"}}true
  {{else if eq $ext "VK_KHR_mir_surface"}}true
  {{else if eq $ext "VK_KHR_win32_surface"}}true
  {{end}}
{{end}}


{{/*
------------------------------------------------------------------------------
  Reports whether an extension is implemented entirely by the loader,
  so drivers should not enumerate it.
------------------------------------------------------------------------------
*/}}
{{define "IsLoaderExtension"}}
  {{$ext := index $.Arguments 0}}
  {{     if eq $ext "VK_KHR_surface"}}true
  {{else if eq $ext "VK_KHR_swapchain"}}true
  {{else if eq $ext "VK_KHR_android_surface"}}true
  {{end}}
{{end}}

vulkan/libvulkan/dispatch_gen.cpp

deleted100644 → 0
+0 −160

File deleted.

Preview size limit exceeded, changes collapsed.

vulkan/libvulkan/dispatch_gen.h

deleted100644 → 0
+0 −52
Original line number Diff line number Diff line
/*
 * 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.
 */

// WARNING: This file is generated. See ../README.md for instructions.

#include <vulkan/vk_android_native_buffer.h>
#include <vulkan/vulkan.h>

namespace vulkan {

struct DriverDispatchTable {
    // clang-format off
    PFN_vkDestroyInstance DestroyInstance;
    PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices;
    PFN_vkGetPhysicalDeviceProperties GetPhysicalDeviceProperties;
    PFN_vkGetPhysicalDeviceQueueFamilyProperties GetPhysicalDeviceQueueFamilyProperties;
    PFN_vkGetPhysicalDeviceMemoryProperties GetPhysicalDeviceMemoryProperties;
    PFN_vkGetPhysicalDeviceFeatures GetPhysicalDeviceFeatures;
    PFN_vkGetPhysicalDeviceFormatProperties GetPhysicalDeviceFormatProperties;
    PFN_vkGetPhysicalDeviceImageFormatProperties GetPhysicalDeviceImageFormatProperties;
    PFN_vkCreateDevice CreateDevice;
    PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties;
    PFN_vkGetPhysicalDeviceSparseImageFormatProperties GetPhysicalDeviceSparseImageFormatProperties;
    PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT;
    PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT;
    PFN_vkDebugReportMessageEXT DebugReportMessageEXT;
    PFN_vkGetDeviceProcAddr GetDeviceProcAddr;
    PFN_vkDestroyDevice DestroyDevice;
    PFN_vkGetDeviceQueue GetDeviceQueue;
    PFN_vkAllocateCommandBuffers AllocateCommandBuffers;
    PFN_vkCreateImage CreateImage;
    PFN_vkDestroyImage DestroyImage;
    PFN_vkGetSwapchainGrallocUsageANDROID GetSwapchainGrallocUsageANDROID;
    PFN_vkAcquireImageANDROID AcquireImageANDROID;
    PFN_vkQueueSignalReleaseImageANDROID QueueSignalReleaseImageANDROID;
    // clang-format on
};

}  // namespace vulkan
Loading