Skip to content

Commit a89e926

Browse files
committed
Pass through direct to driver for no-op intercepts
1 parent 34fef5a commit a89e926

File tree

12 files changed

+119
-37
lines changed

12 files changed

+119
-37
lines changed

generator/vk_codegen/device_dispatch_table.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,14 @@ struct DeviceInterceptTableEntry
2626
* @brief The layer function pointer.
2727
*/
2828
PFN_vkVoidFunction function;
29+
30+
/**
31+
* @brief The layer default function pointer.
32+
*/
33+
PFN_vkVoidFunction defaultFunction;
2934
};
3035

31-
#define ENTRY(fnc) { STR(fnc), reinterpret_cast<PFN_vkVoidFunction>(layer_##fnc<user_tag>) }
36+
#define ENTRY(fnc) { STR(fnc), reinterpret_cast<PFN_vkVoidFunction>(layer_##fnc<user_tag>), reinterpret_cast<PFN_vkVoidFunction>(layer_##fnc<default_tag>) }
3237

3338
/**
3439
* @brief The device dispatch table used to call the driver.

generator/vk_codegen/instance_dispatch_table.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,14 @@ struct InstanceInterceptTableEntry
2727
* @brief The layer function pointer.
2828
*/
2929
PFN_vkVoidFunction function;
30+
31+
/**
32+
* @brief The layer default function pointer.
33+
*/
34+
PFN_vkVoidFunction defaultFunction;
3035
};
3136

32-
#define ENTRY(fnc) { STR(fnc), reinterpret_cast<PFN_vkVoidFunction>(layer_##fnc<user_tag>) }
37+
#define ENTRY(fnc) { STR(fnc), reinterpret_cast<PFN_vkVoidFunction>(layer_##fnc<user_tag>), reinterpret_cast<PFN_vkVoidFunction>(layer_##fnc<default_tag>) }
3338

3439
/**
3540
* @brief The instance dispatch table used to call the driver.

generator/vk_layer/source/instance.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ class Instance
128128
VkInstance instance;
129129

130130
/**
131-
* @brief The next layer's \c vkGetInstanceProcAddr() function pointer.
131+
* @brief The next layer's @c vkGetInstanceProcAddr() function pointer.
132132
*/
133133
PFN_vkGetInstanceProcAddr nlayerGetProcAddress;
134134

layer_example/source/instance.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ class Instance
122122
VkInstance instance;
123123

124124
/**
125-
* @brief The next layer's \c vkGetInstanceProcAddr() function pointer.
125+
* @brief The next layer's @c vkGetInstanceProcAddr() function pointer.
126126
*/
127127
PFN_vkGetInstanceProcAddr nlayerGetProcAddress;
128128

layer_gpu_profile/source/instance.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ class Instance
123123
VkInstance instance;
124124

125125
/**
126-
* @brief The next layer's \c vkGetInstanceProcAddr() function pointer.
126+
* @brief The next layer's @c vkGetInstanceProcAddr() function pointer.
127127
*/
128128
PFN_vkGetInstanceProcAddr nlayerGetProcAddress;
129129

layer_gpu_support/source/instance.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ class Instance
122122
VkInstance instance;
123123

124124
/**
125-
* @brief The next layer's \c vkGetInstanceProcAddr() function pointer.
125+
* @brief The next layer's @c vkGetInstanceProcAddr() function pointer.
126126
*/
127127
PFN_vkGetInstanceProcAddr nlayerGetProcAddress;
128128

layer_gpu_timeline/source/instance.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ class Instance
122122
VkInstance instance;
123123

124124
/**
125-
* @brief The next layer's \c vkGetInstanceProcAddr() function pointer.
125+
* @brief The next layer's @c vkGetInstanceProcAddr() function pointer.
126126
*/
127127
PFN_vkGetInstanceProcAddr nlayerGetProcAddress;
128128

source_common/framework/device_dispatch_table.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,14 @@ struct DeviceInterceptTableEntry
5151
* @brief The layer function pointer.
5252
*/
5353
PFN_vkVoidFunction function;
54+
55+
/**
56+
* @brief The layer default function pointer.
57+
*/
58+
PFN_vkVoidFunction defaultFunction;
5459
};
5560

56-
#define ENTRY(fnc) { STR(fnc), reinterpret_cast<PFN_vkVoidFunction>(layer_##fnc<user_tag>) }
61+
#define ENTRY(fnc) { STR(fnc), reinterpret_cast<PFN_vkVoidFunction>(layer_##fnc<user_tag>), reinterpret_cast<PFN_vkVoidFunction>(layer_##fnc<default_tag>) }
5762

5863
/**
5964
* @brief The device dispatch table used to call the driver.

source_common/framework/instance_dispatch_table.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,14 @@ struct InstanceInterceptTableEntry
5252
* @brief The layer function pointer.
5353
*/
5454
PFN_vkVoidFunction function;
55+
56+
/**
57+
* @brief The layer default function pointer.
58+
*/
59+
PFN_vkVoidFunction defaultFunction;
5560
};
5661

57-
#define ENTRY(fnc) { STR(fnc), reinterpret_cast<PFN_vkVoidFunction>(layer_##fnc<user_tag>) }
62+
#define ENTRY(fnc) { STR(fnc), reinterpret_cast<PFN_vkVoidFunction>(layer_##fnc<user_tag>), reinterpret_cast<PFN_vkVoidFunction>(layer_##fnc<default_tag>) }
5863

5964
/**
6065
* @brief The instance dispatch table used to call the driver.

source_common/framework/manual_functions.cpp

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
* implemented as library code which can be swapped for alternative
3030
* implementations on a per-layer basis if needed.
3131
*/
32+
3233
#include <vulkan/utility/vk_struct_helper.hpp>
3334

3435
#include "framework/manual_functions.hpp"
@@ -111,7 +112,35 @@ VkLayerDeviceCreateInfo* getChainInfo(const VkDeviceCreateInfo* pCreateInfo)
111112
}
112113

113114
/* See header for documentation. */
114-
std::pair<bool, PFN_vkVoidFunction> getInstanceLayerFunction(const char* name)
115+
bool isFunctionAlwaysExported(const char* name)
116+
{
117+
const std::array<const char*, 11> alwaysExportedFunctions {
118+
"vkGetInstanceProcAddr",
119+
"vkGetDeviceProcAddr",
120+
"vkEnumerateInstanceExtensionProperties",
121+
"vkEnumerateDeviceExtensionProperties",
122+
"vkEnumerateInstanceLayerProperties",
123+
"vkEnumerateDeviceLayerProperties",
124+
"vkCreateInstance",
125+
"vkDestroyInstance",
126+
"vkCreateDevice",
127+
"vkDestroyDevice",
128+
"vkGetDeviceImageMemoryRequirementsKHR",
129+
};
130+
131+
for (const char* functionName : alwaysExportedFunctions)
132+
{
133+
if (!strcmp(functionName, name))
134+
{
135+
return true;
136+
}
137+
}
138+
139+
return false;
140+
}
141+
142+
/* See header for documentation. */
143+
std::tuple<bool, PFN_vkVoidFunction, PFN_vkVoidFunction> getInstanceLayerFunction(const char* name)
115144
{
116145
const std::array<const char*, 5> globalFunctions {
117146
// Supported since Vulkan 1.0
@@ -125,7 +154,7 @@ std::pair<bool, PFN_vkVoidFunction> getInstanceLayerFunction(const char* name)
125154
};
126155

127156
bool isGlobal {false};
128-
for (const auto* globalName : globalFunctions)
157+
for (const char* globalName : globalFunctions)
129158
{
130159
if (!strcmp(globalName, name))
131160
{
@@ -138,25 +167,25 @@ std::pair<bool, PFN_vkVoidFunction> getInstanceLayerFunction(const char* name)
138167
{
139168
if (!strcmp(function.name, name))
140169
{
141-
return {isGlobal, function.function};
170+
return std::make_tuple(isGlobal, function.function, function.defaultFunction);
142171
}
143172
}
144173

145-
return {isGlobal, nullptr};
174+
return std::make_tuple(isGlobal, nullptr, nullptr);
146175
}
147176

148177
/* See header for documentation. */
149-
PFN_vkVoidFunction getDeviceLayerFunction(const char* name)
178+
std::pair<PFN_vkVoidFunction, PFN_vkVoidFunction> getDeviceLayerFunction(const char* name)
150179
{
151180
for (auto& function : deviceIntercepts)
152181
{
153182
if (!strcmp(function.name, name))
154183
{
155-
return function.function;
184+
return {function.function, function.defaultFunction};
156185
}
157186
}
158187

159-
return nullptr;
188+
return {nullptr, nullptr};
160189
}
161190

162191
/* See header for documentation. */
@@ -497,7 +526,7 @@ void enableDeviceVkExtImageCompressionControl(Instance& instance,
497526
/** See Vulkan API for documentation. */
498527
PFN_vkVoidFunction layer_vkGetInstanceProcAddr_default(VkInstance instance, const char* pName)
499528
{
500-
auto [isGlobal, layerFunction] = getInstanceLayerFunction(pName);
529+
auto [isGlobal, layerFunction, layerDefaultFunction] = getInstanceLayerFunction(pName);
501530

502531
// Global functions must be exposed and do not require the caller to pass
503532
// a valid instance pointer, although it is required to be nullptr in
@@ -507,6 +536,15 @@ PFN_vkVoidFunction layer_vkGetInstanceProcAddr_default(VkInstance instance, cons
507536
return layerFunction;
508537
}
509538

539+
// Function is not exported because layer doesn't implement it at all
540+
bool exportLayerFunction { layerFunction != nullptr };
541+
542+
// Function is not exported because layer doesn't specialize a user_tag version
543+
if (!isFunctionAlwaysExported(pName) && layerFunction == layerDefaultFunction)
544+
{
545+
exportLayerFunction = false;
546+
}
547+
510548
// For other functions, only expose functions that the driver exposes to
511549
// avoid changing queryable interface behavior seen by the application
512550
if (instance)
@@ -519,7 +557,7 @@ PFN_vkVoidFunction layer_vkGetInstanceProcAddr_default(VkInstance instance, cons
519557
PFN_vkVoidFunction driverFunction = layer->nlayerGetProcAddress(instance, pName);
520558

521559
// If driver exposes it and the layer has one, use the layer function
522-
if (driverFunction && layerFunction)
560+
if (driverFunction && exportLayerFunction)
523561
{
524562
return layerFunction;
525563
}
@@ -542,10 +580,19 @@ PFN_vkVoidFunction layer_vkGetDeviceProcAddr_default(VkDevice device, const char
542580
// Only expose functions that the driver exposes to avoid changing
543581
// queryable interface behavior seen by the application
544582
auto driverFunction = layer->driver.vkGetDeviceProcAddr(device, pName);
545-
auto layerFunction = getDeviceLayerFunction(pName);
583+
auto [layerFunction, layerDefaultFunction] = getDeviceLayerFunction(pName);
584+
585+
// Function is not exported because layer doesn't implement it at all
586+
bool exportLayerFunction { layerFunction != nullptr };
587+
588+
// Function is not exported because layer doesn't specialize a user_tag version
589+
if (!isFunctionAlwaysExported(pName) && layerFunction == layerDefaultFunction)
590+
{
591+
exportLayerFunction = false;
592+
}
546593

547594
// If driver exposes it and the layer has one, use the layer function
548-
if (driverFunction && layerFunction)
595+
if (driverFunction && exportLayerFunction)
549596
{
550597
return layerFunction;
551598
}

0 commit comments

Comments
 (0)