vulkan: Implement new vkGet*ProcAddrBehavior
The primary goal of this change is to switch to the revised GPA
behavior:
- GIPA(NULL, ..) only works for non-dispatched (global) commands
- GIPA(instance, ..) returns functions for commands that dispatch on any
object type, and the function works for any object of the appropriate
type if it is a child of the instance.
- GDPA(NULL, ..) returns NULL.
- GDPA(device, ..) returns a device-specific function for the command.
This change refactors/tidies many of the things it modified. Some
notable changes:
- All the loader generated code is now in dispatch.tmpl ->
dispatch_gen.{h,cpp}, instead of two separate templates.
- Reorganization allowed generating the dispatch table structures,
eliminating one source of frequent bugs.
- Removes some error-prone macro duplication.
- Handling of extensions and special loader functions is now much
more uniform and hopefully clearer.
- Loader top- and bottom-level functions are now consistently named with
_Top and _Bottom suffixes, and are grouped by level in loader.cpp.
- The VkInstance and VkDevice implementations are no longer derived from
::VkInstance_T and ::VkDevice_T. Was more trouble than it was worth.
- Renamed 'vtbl' to 'dispatch' in most places.
- Renamed nulldrv template and generated files to match the loader
naming pattern: null_driver.tmpl -> null_driver_gen.{h,cpp}
- Now all the entry point prototypes are generated, instead of having
to be updated by hand (another source of several bugs).
Change-Id: Ic263f802d0d523b18a0f00420b3a722aa04ce299
(cherry picked from commit 3cffb8e837222f413a1fe53522e2cc33366b8eeb)
diff --git a/vulkan/nulldrv/null_driver.tmpl b/vulkan/nulldrv/null_driver.tmpl
new file mode 100644
index 0000000..7762011
--- /dev/null
+++ b/vulkan/nulldrv/null_driver.tmpl
@@ -0,0 +1,222 @@
+{{/*
+ * 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 "null_driver_gen.h" | Format (Global "clang-format") | Write "null_driver_gen.h" }}
+{{$ | Macro "null_driver_gen.cpp" | Format (Global "clang-format") | Write "null_driver_gen.cpp"}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+ null_driver_gen.h
+-------------------------------------------------------------------------------
+*/}}
+{{define "null_driver_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.
+•*/
+¶
+// This file is generated. Do not edit manually!
+// To regenerate: $ apic template ../api/vulkan.api null_driver.tmpl
+// Requires apic from https://android.googlesource.com/platform/tools/gpu/.
+¶
+#ifndef NULLDRV_NULL_DRIVER_H
+#define NULLDRV_NULL_DRIVER_H 1
+¶
+#define VK_PROTOTYPES
+#include <vulkan/vk_android_native_buffer.h>
+#include <vulkan/vulkan.h>
+¶
+namespace null_driver {«
+¶
+PFN_vkVoidFunction GetGlobalProcAddr(const char* name);
+PFN_vkVoidFunction GetInstanceProcAddr(const char* name);
+¶
+// clang-format off
+ {{range $f := AllCommands $}}
+ {{if (Macro "IsDriverFunction" $f)}}
+VKAPI_ATTR {{Node "Type" $f.Return}} {{Macro "BaseName" $f}}({{Macro "Parameters" $f}});
+ {{end}}
+ {{end}}
+VKAPI_ATTR VkResult GetSwapchainGrallocUsageANDROID(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, int* grallocUsage);
+VKAPI_ATTR VkResult AcquireImageANDROID(VkDevice device, VkImage image, int nativeFenceFd, VkSemaphore semaphore, VkFence fence);
+VKAPI_ATTR VkResult QueueSignalReleaseImageANDROID(VkQueue queue, VkImage image, int* pNativeFenceFd);
+// clang-format on
+¶
+»} // namespace null_driver
+¶
+#endif // NULLDRV_NULL_DRIVER_H
+¶{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+ null_driver_gen.cpp
+-------------------------------------------------------------------------------
+*/}}
+{{define "null_driver_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.
+•*/
+¶
+// This file is generated. Do not edit manually!
+// To regenerate: $ apic template ../api/vulkan.api null_driver.tmpl
+// Requires apic from https://android.googlesource.com/platform/tools/gpu/.
+¶
+#include "null_driver_gen.h"
+#include <algorithm>
+¶
+using namespace null_driver;
+¶
+namespace {
+¶
+struct NameProc {
+ const char* name;
+ PFN_vkVoidFunction proc;
+};
+¶
+PFN_vkVoidFunction Lookup(const char* name,
+ const NameProc* begin,
+ const NameProc* end) {
+ const auto& entry = std::lower_bound(
+ begin, end, name,
+ [](const NameProc& e, const char* n) { return strcmp(e.name, n) < 0; });
+ if (entry == end || strcmp(entry->name, name) != 0)
+ return nullptr;
+ return entry->proc;
+}
+¶
+template <size_t N>
+PFN_vkVoidFunction Lookup(const char* name, const NameProc (&procs)[N]) {
+ return Lookup(name, procs, procs + N);
+}
+¶
+const NameProc kGlobalProcs[] = {«
+ // clang-format off
+ {{range $f := SortBy (AllCommands $) "FunctionName"}}
+ {{if and (Macro "IsDriverFunction" $f) (eq (Macro "Vtbl" $f) "Global")}}
+ {"{{$f.Name}}", reinterpret_cast<PFN_vkVoidFunction>(§
+ static_cast<{{Macro "FunctionPtrName" $f}}>(§
+ {{Macro "BaseName" $f}}))},
+ {{end}}
+ {{end}}
+ // clang-format on
+»};
+¶
+const NameProc kInstanceProcs[] = {«
+ // clang-format off
+ {{range $f := SortBy (AllCommands $) "FunctionName"}}
+ {{if (Macro "IsDriverFunction" $f)}}
+ {"{{$f.Name}}", reinterpret_cast<PFN_vkVoidFunction>(§
+ static_cast<{{Macro "FunctionPtrName" $f}}>(§
+ {{Macro "BaseName" $f}}))},
+ {{end}}
+ {{end}}
+ // clang-format on
+»};
+¶
+} // namespace
+¶
+namespace null_driver {
+¶
+PFN_vkVoidFunction GetGlobalProcAddr(const char* name) {
+ return Lookup(name, kGlobalProcs);
+}
+¶
+PFN_vkVoidFunction GetInstanceProcAddr(const char* name) {«
+ PFN_vkVoidFunction pfn;
+ if ((pfn = Lookup(name, kInstanceProcs)))
+ return pfn;
+ if (strcmp(name, "vkGetSwapchainGrallocUsageANDROID") == 0)
+ return reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetSwapchainGrallocUsageANDROID>(GetSwapchainGrallocUsageANDROID));
+ if (strcmp(name, "vkAcquireImageANDROID") == 0)
+ return reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkAcquireImageANDROID>(AcquireImageANDROID));
+ if (strcmp(name, "vkQueueSignalReleaseImageANDROID") == 0)
+ return reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkQueueSignalReleaseImageANDROID>(QueueSignalReleaseImageANDROID));
+ return nullptr;
+»}
+¶
+} // namespace null_driver
+¶
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+ Emits a function name without the "vk" prefix.
+-------------------------------------------------------------------------------
+*/}}
+{{define "BaseName"}}
+ {{AssertType $ "Function"}}
+ {{TrimPrefix "vk" $.Name}}
+{{end}}
+
+
+{{/*
+------------------------------------------------------------------------------
+ Emits 'true' if the API function is implemented by the driver.
+------------------------------------------------------------------------------
+*/}}
+{{define "IsDriverFunction"}}
+ {{AssertType $ "Function"}}
+
+ {{if not (GetAnnotation $ "pfn")}}
+ {{$ext := GetAnnotation $ "extension"}}
+ {{if $ext}}
+ {{Macro "IsDriverExtension" $ext}}
+ {{else}}
+ true
+ {{end}}
+ {{end}}
+{{end}}
+
+
+{{/*
+------------------------------------------------------------------------------
+ Reports whether an extension is implemented by the driver.
+------------------------------------------------------------------------------
+*/}}
+{{define "IsDriverExtension"}}
+ {{$ext := index $.Arguments 0}}
+ {{if eq $ext "VK_ANDROID_native_buffer"}}true
+ {{end}}
+{{end}}