Skip to content

Commit

Permalink
Lazily resolve Vulkan commands
Browse files Browse the repository at this point in the history
This is probably the 'minimum changes' approach. It uses lambda
functions, which will take a copy of the handles used for command resolving.
  • Loading branch information
Qining committed Jun 15, 2018
1 parent c578d8c commit f6fda92
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 7 deletions.
17 changes: 17 additions & 0 deletions gapir/cc/vulkan_gfx_api.inc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,23 @@ typedef struct {

IndirectMaps mIndirectMaps;

template <typename FuncPtr>
class LazyResolved {
public:
LazyResolved(std::function<void*()> resolver):resolve_(resolver), ptr_(nullptr) {}

template <typename... Args>
typename std::result_of<FuncPtr(Args...)>::type operator()(Args&&... args) {
if (!ptr_) {
ptr_ = reinterpret_cast<FuncPtr>(resolve_());
}
return ptr_(std::forward<Args>(args)...);
}
private:
std::function<void*()> resolve_;
FuncPtr ptr_ = nullptr;
};

// Function for wrapping around the normal vkCreateInstance to:
// 1) inject virtual swapchain as an additional enabled layer;
// 2) drop validation layers and debug report extension if requested;
Expand Down
36 changes: 36 additions & 0 deletions gapis/api/templates/cpp_common.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -1095,6 +1095,18 @@
{{end}}


{{/*
-------------------------------------------------------------------------------
Emits the std::function alias name for a given command.
-------------------------------------------------------------------------------
*/}}
{{define "C++.StdFunctionType"}}
{{AssertType $ "Function"}}

StdFunction{{Macro "CmdName" $ | Upper}}
{{end}}


{{/*
-------------------------------------------------------------------------------
Emits the C++ function-pointer typedef for a given command.
Expand All @@ -1107,6 +1119,18 @@
{{end}}


{{/*
-------------------------------------------------------------------------------
Emits the C++ std::function alias for a given command.
-------------------------------------------------------------------------------
*/}}
{{define "C++.DefStdFunctionAlias"}}
{{AssertType $ "Function"}}

using {{Template "C++.StdFunctionType" $}} = std::function<{{Template "C++.ReturnType" $}}({{Template "C++.CallParameters" $}})>;
{{end}}


{{/*
-------------------------------------------------------------------------------
Emits the C++ function-pointer variable extern for a given command.
Expand All @@ -1119,6 +1143,18 @@
{{end}}


{{/*
-------------------------------------------------------------------------------
Emits the C++ std::function variable extern for a given command.
-------------------------------------------------------------------------------
*/}}
{{define "C++.StdFunctionDecl"}}
{{AssertType $ "Function"}}

{{Template "C++.StdFunctionType" $}} {{Template "CmdName" $}}
{{end}}


{{/*
-------------------------------------------------------------------------------
Emits the method name for the given command or subroutine.
Expand Down
4 changes: 3 additions & 1 deletion gapis/api/templates/specific_gfx_api.h.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "core/cc/{{Global "API"}}_ptr_types.h"
#include <stdint.h>
#include <functional>
#include <string>
{{/* Forward declare structs used by the graphics API in the global namespace. */}}
Expand Down Expand Up @@ -80,6 +81,7 @@ class {{Title (Global "API")}} : public Api {
{{range $c := AllCommands $}}
{{if not (GetAnnotation $c "synthetic")}}
{{Template "C++.TypedefFunctionPtr" $c}}
{{Template "C++.DefStdFunctionAlias" $c}}
{{end}}
{{end}}
Expand All @@ -88,7 +90,7 @@ class {{Title (Global "API")}} : public Api {
struct {{$table}}FunctionStubs {
{{range $f := $p}}
{{if and (not (GetAnnotation $f "synthetic")) (not (GetAnnotation $f "pfn"))}}
{{Template "C++.FunctionPtrDecl" $f}} = nullptr;
{{Template "C++.StdFunctionDecl" $f}} = nullptr;
{{end}}
{{end}}
};
Expand Down
12 changes: 6 additions & 6 deletions gapis/api/templates/vulkan_gfx_api_extras.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@

std::vector<Vulkan::VkPhysicalDevice> getVkPhysicalDevices(§
Vulkan::PFNVKENUMERATEPHYSICALDEVICES vkEnumeratePhysicalDevices, Vulkan::VkInstance instance) {
Vulkan::StdFunctionVKENUMERATEPHYSICALDEVICES vkEnumeratePhysicalDevices, Vulkan::VkInstance instance) {
uint32_t count = 0;
vkEnumeratePhysicalDevices(instance, &count, nullptr);
std::vector<Vulkan::VkPhysicalDevice> devices(count);
Expand All @@ -73,7 +73,7 @@
}
std::vector<Vulkan::VkQueue> getVkQueues(§
Vulkan::PFNVKGETDEVICEQUEUE vkGetDeviceQueue, Vulkan::VkDevice device, §
Vulkan::StdFunctionVKGETDEVICEQUEUE vkGetDeviceQueue, Vulkan::VkDevice device, §
Vulkan::VkDeviceCreateInfo* createInfo) {
std::vector<Vulkan::VkQueue> queues;
for (uint32_t i = 0; i < createInfo->queueCreateInfoCount; ++i) {
Expand Down Expand Up @@ -204,8 +204,8 @@ bool Vulkan::replayCreateVkDeviceImpl(Stack* stack, size_val physicalDevice,
{{range $c := AllCommands $}}
{{if (Macro "IsIndirected" "Command" $c "IndirectOn" "VkInstance")}}
{{$name := Macro "CmdName" $c}}
stubs.{{$name}} = reinterpret_cast<{{Template "C++.FunctionPtrType" $c}}>(§
core::GetVulkanInstanceProcAddress(instance, "{{$name}}", false));
stubs.{{$name}} = Vulkan::LazyResolved<{{Template "C++.FunctionPtrType" $c}}>(
[instance]() -> void* { return core::GetVulkanInstanceProcAddress(instance, "{{$name}}", false); });
{{end}}
{{end}}
// Get all physical devices for this instance and bind them.
Expand Down Expand Up @@ -255,8 +255,8 @@ bool Vulkan::replayCreateVkDeviceImpl(Stack* stack, size_val physicalDevice,
{{range $c := AllCommands $}}
{{if (Macro "IsIndirected" "Command" $c "IndirectOn" "VkDevice")}}
{{$name := Macro "CmdName" $c}}
stubs.{{$name}} = reinterpret_cast<{{Template "C++.FunctionPtrType" $c}}>(§
core::GetVulkanDeviceProcAddress(instance, device, "{{$name}}", false));
stubs.{{$name}} = Vulkan::LazyResolved<{{Template "C++.FunctionPtrType" $c}}>(
[instance, device]() -> void* { return core::GetVulkanDeviceProcAddress(instance, device, "{{$name}}", false); });
{{end}}
{{end}}
// Get all queues for this device and bind them.
Expand Down

0 comments on commit f6fda92

Please sign in to comment.