Skip to content

Commit 8712e51

Browse files
committed
Switch VkDeviceCreateInfo to use patch callbacks
1 parent d419b5d commit 8712e51

File tree

10 files changed

+132
-74
lines changed

10 files changed

+132
-74
lines changed

generator/vk_layer/source/device.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
static std::unordered_map<void*, std::unique_ptr<Device>> g_devices;
4141

4242
/* See header for documentation. */
43-
const std::vector<std::string> Device::extraExtensions { };
43+
const std::vector<DeviceCreatePatchPtr> Device::createInfoPatches {};
4444

4545
/* See header for documentation. */
4646
void Device::store(

generator/vk_layer/source/device.hpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,22 @@
5252

5353
#pragma once
5454

55+
#include <string>
56+
#include <vector>
57+
#include <vulkan/utility/vk_safe_struct.hpp>
5558
#include <vulkan/vk_layer.h>
5659

5760
#include "framework/device_dispatch_table.hpp"
58-
5961
#include "instance.hpp"
6062

63+
/**
64+
* @brief Function pointer type for patching VkDeviceCreateInfo.
65+
*/
66+
using DeviceCreatePatchPtr = void (*)(Instance& instance,
67+
VkPhysicalDevice physicalDevice,
68+
vku::safe_VkDeviceCreateInfo& createInfo,
69+
std::vector<std::string>& supported);
70+
6171
/**
6272
* @brief This class implements the layer state tracker for a single device.
6373
*/
@@ -144,7 +154,7 @@ class Device
144154
/**
145155
* @brief The minimum set of device extensions needed by this layer.
146156
*/
147-
static const std::vector<std::string> extraExtensions;
157+
static const std::vector<DeviceCreatePatchPtr> createInfoPatches;
148158

149159
private:
150160
/**

layer_example/source/device.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
static std::unordered_map<void*, std::unique_ptr<Device>> g_devices;
4242

4343
/* See header for documentation. */
44-
const std::vector<std::string> Device::extraExtensions {};
44+
const std::vector<DeviceCreatePatchPtr> Device::createInfoPatches {};
4545

4646
/* See header for documentation. */
4747
void Device::store(VkDevice handle, std::unique_ptr<Device> device)

layer_example/source/device.hpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,21 @@
5252

5353
#pragma once
5454

55+
#include <string>
56+
#include <vector>
57+
#include <vulkan/utility/vk_safe_struct.hpp>
58+
#include <vulkan/vk_layer.h>
59+
5560
#include "framework/device_dispatch_table.hpp"
5661
#include "instance.hpp"
5762

58-
#include <vulkan/vk_layer.h>
63+
/**
64+
* @brief Function pointer type for patching VkDeviceCreateInfo.
65+
*/
66+
using DeviceCreatePatchPtr = void (*)(Instance& instance,
67+
VkPhysicalDevice physicalDevice,
68+
vku::safe_VkDeviceCreateInfo& createInfo,
69+
std::vector<std::string>& supported);
5970

6071
/**
6172
* @brief This class implements the layer state tracker for a single device.
@@ -134,9 +145,9 @@ class Device
134145
DeviceDispatchTable driver {};
135146

136147
/**
137-
* @brief The minimum set of device extensions needed by this layer.
148+
* @brief The set of VkCreateDeviceInfo patches needed by this layer.
138149
*/
139-
static const std::vector<std::string> extraExtensions;
150+
static const std::vector<DeviceCreatePatchPtr> createInfoPatches;
140151

141152
private:
142153
/**

layer_gpu_support/source/device.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323
* ----------------------------------------------------------------------------
2424
*/
2525

26-
#include "device.hpp"
26+
#include <vulkan/utility/vk_struct_helper.hpp>
2727

28+
#include "device.hpp"
29+
#include "framework/manual_functions.hpp"
2830
#include "framework/utils.hpp"
2931
#include "instance.hpp"
3032

@@ -34,9 +36,9 @@
3436
static std::unordered_map<void*, std::unique_ptr<Device>> g_devices;
3537

3638
/* See header for documentation. */
37-
const std::vector<std::string> Device::extraExtensions {
38-
VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME,
39-
VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME,
39+
const std::vector<DeviceCreatePatchPtr> Device::createInfoPatches {
40+
enableDeviceVkKhrTimelineSemaphore,
41+
enableDeviceVkExtImageCompressionControl
4042
};
4143

4244
/* See header for documentation. */

layer_gpu_support/source/device.hpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,23 @@
5252

5353
#pragma once
5454

55+
#include <string>
56+
#include <vector>
57+
#include <vulkan/utility/vk_safe_struct.hpp>
58+
#include <vulkan/vk_layer.h>
59+
5560
#include "framework/device_dispatch_table.hpp"
5661
#include "instance.hpp"
5762

58-
#include <vulkan/vk_layer.h>
63+
64+
65+
/**
66+
* @brief Function pointer type for patching VkDeviceCreateInfo.
67+
*/
68+
using DeviceCreatePatchPtr = void (*)(Instance& instance,
69+
VkPhysicalDevice physicalDevice,
70+
vku::safe_VkDeviceCreateInfo& createInfo,
71+
std::vector<std::string>& supported);
5972

6073
/**
6174
* @brief This class implements the layer state tracker for a single device.
@@ -149,9 +162,9 @@ class Device
149162
DeviceDispatchTable driver {};
150163

151164
/**
152-
* @brief The minimum set of device extensions needed by this layer.
165+
* @brief The set of VkCreateDeviceInfo patches needed by this layer.
153166
*/
154-
static const std::vector<std::string> extraExtensions;
167+
static const std::vector<DeviceCreatePatchPtr> createInfoPatches;
155168

156169
/**
157170
* @brief The timeline sem use for queue serialization.

layer_gpu_timeline/source/device.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,23 @@
2222
* IN THE SOFTWARE.
2323
* ----------------------------------------------------------------------------
2424
*/
25-
26-
#include "device.hpp"
25+
#include <vector>
26+
#include <sys/stat.h>
27+
#include <unistd.h>
2728

2829
#include "comms/comms_module.hpp"
30+
#include "device.hpp"
2931
#include "framework/utils.hpp"
3032
#include "instance.hpp"
3133
#include "timeline_protobuf_encoder.hpp"
3234

33-
#include <vector>
34-
35-
#include <sys/stat.h>
36-
#include <unistd.h>
37-
3835
/**
3936
* @brief The dispatch lookup for all of the created Vulkan devices.
4037
*/
4138
static std::unordered_map<void*, std::unique_ptr<Device>> g_devices;
4239

4340
/* See header for documentation. */
44-
const std::vector<std::string> Device::extraExtensions {};
41+
const std::vector<DeviceCreatePatchPtr> Device::createInfoPatches {};
4542

4643
/* See header for documentation. */
4744
std::unique_ptr<Comms::CommsModule> Device::commsModule;

layer_gpu_timeline/source/device.hpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,24 @@
5252

5353
#pragma once
5454

55+
#include <string>
56+
#include <vector>
57+
#include <vulkan/utility/vk_safe_struct.hpp>
58+
#include <vulkan/vk_layer.h>
59+
5560
#include "comms/comms_module.hpp"
5661
#include "framework/device_dispatch_table.hpp"
5762
#include "instance.hpp"
5863
#include "timeline_comms.hpp"
5964
#include "trackers/device.hpp"
6065

61-
#include <vulkan/vk_layer.h>
66+
/**
67+
* @brief Function pointer type for patching VkDeviceCreateInfo.
68+
*/
69+
using DeviceCreatePatchPtr = void (*)(Instance& instance,
70+
VkPhysicalDevice physicalDevice,
71+
vku::safe_VkDeviceCreateInfo& createInfo,
72+
std::vector<std::string>& supported);
6273

6374
/**
6475
* @brief This class implements the layer state tracker for a single device.
@@ -164,9 +175,9 @@ class Device
164175
DeviceDispatchTable driver {};
165176

166177
/**
167-
* @brief The minimum set of device extensions needed by this layer.
178+
* @brief The set of VkCreateDeviceInfo patches needed by this layer.
168179
*/
169-
static const std::vector<std::string> extraExtensions;
180+
static const std::vector<DeviceCreatePatchPtr> createInfoPatches;
170181

171182
private:
172183
/**

source_common/framework/manual_functions.cpp

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

3534
#include "framework/manual_functions.hpp"
@@ -370,22 +369,15 @@ static void enableInstanceVkExtDebugUtils(vku::safe_VkInstanceCreateInfo& create
370369
}
371370
}
372371

373-
/**
374-
* Enable VK_KHR_timeline_semaphore if not enabled.
375-
*
376-
* Enabling this requires passing the extension string to vkCreateDevice(),
377-
* and passing either VkPhysicalDeviceTimelineSemaphoreFeatures or
378-
* VkPhysicalDeviceVulkan12Features with the feature enabled.
379-
*
380-
* If the user has the extension enabled but the feature disabled we patch
381-
* their existing structures to enable it.
382-
*
383-
* @param createInfo The createInfo we can search to find user config.
384-
* @param supported The list of supported extensions.
385-
*/
386-
static void enableDeviceVkKhrTimelineSemaphore(vku::safe_VkDeviceCreateInfo& createInfo,
387-
const std::vector<std::string>& supported)
372+
/* See header for documentation. */
373+
void enableDeviceVkKhrTimelineSemaphore(Instance& instance,
374+
VkPhysicalDevice physicalDevice,
375+
vku::safe_VkDeviceCreateInfo& createInfo,
376+
std::vector<std::string>& supported)
388377
{
378+
UNUSED(instance);
379+
UNUSED(physicalDevice);
380+
389381
static const std::string target {VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME};
390382

391383
// We know we can const-cast here because createInfo is a safe-struct clone
@@ -445,21 +437,15 @@ static void enableDeviceVkKhrTimelineSemaphore(vku::safe_VkDeviceCreateInfo& cre
445437
}
446438
}
447439

448-
/**
449-
* Enable VK_EXT_image_compression_control if not enabled.
450-
*
451-
* Enabling this requires passing the extension string to vkCreateDevice(),
452-
* and passing VkPhysicalDeviceImageCompressionControlFeaturesEXT.
453-
*
454-
* If the user has the extension enabled but the feature disabled we patch
455-
* their existing structures to enable it.
456-
*
457-
* @param createInfo The createInfo we can search to find user config.
458-
* @param supported The list of supported extensions.
459-
*/
460-
static void enableDeviceVkExtImageCompressionControl(vku::safe_VkDeviceCreateInfo& createInfo,
461-
std::vector<std::string>& supported)
440+
/* See header for documentation. */
441+
void enableDeviceVkExtImageCompressionControl(Instance& instance,
442+
VkPhysicalDevice physicalDevice,
443+
vku::safe_VkDeviceCreateInfo& createInfo,
444+
std::vector<std::string>& supported)
462445
{
446+
UNUSED(instance);
447+
UNUSED(physicalDevice);
448+
463449
static const std::string target {VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME};
464450

465451
// We know we can const-cast here because createInfo is a safe-struct clone
@@ -792,32 +778,19 @@ VKAPI_ATTR VkResult VKAPI_CALL layer_vkCreateDevice_default(VkPhysicalDevice phy
792778
vku::safe_VkDeviceCreateInfo newCreateInfoSafe(pCreateInfo);
793779
auto* newCreateInfo = reinterpret_cast<VkDeviceCreateInfo*>(&newCreateInfoSafe);
794780

795-
// Enable extra extensions
796-
for (const auto& newExt : Device::extraExtensions)
781+
// Apply all required patches to the VkDeviceCreateInfo
782+
for (const auto patch : Device::createInfoPatches)
797783
{
798-
if (newExt == VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME)
799-
{
800-
801-
enableDeviceVkKhrTimelineSemaphore(newCreateInfoSafe,
802-
supportedExtensions);
803-
}
804-
else if (newExt == VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME)
805-
{
806-
enableDeviceVkExtImageCompressionControl(newCreateInfoSafe,
807-
supportedExtensions);
808-
}
809-
else
810-
{
811-
LAYER_ERR("Unknown instance extension: %s", newExt.c_str());
812-
}
784+
patch(*layer, physicalDevice, newCreateInfoSafe, supportedExtensions);
813785
}
814786

815-
// Log extensions for debug purposes
787+
// Log extensions after patching for debug purposes
816788
for (uint32_t i = 0; i < newCreateInfo->enabledExtensionCount; i++)
817789
{
818790
LAYER_LOG("Requested device extension list: [%u] = %s", i, newCreateInfo->ppEnabledExtensionNames[i]);
819791
}
820792

793+
// TODO: Issue #123: Why can't we just use layer.driver.vkGetInstanceProcAddr?
821794
auto fpCreateDeviceRaw = fpGetInstanceProcAddr(layer->instance, "vkCreateDevice");
822795
auto fpCreateDevice = reinterpret_cast<PFN_vkCreateDevice>(fpCreateDeviceRaw);
823796
if (!fpCreateDevice)

source_common/framework/manual_functions.hpp

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
* implemented as library code which can be swapped for alternative
3030
* implementations on a per-layer basis if needed.
3131
*/
32-
#include "device.hpp"
32+
#include <vulkan/utility/vk_safe_struct.hpp>
33+
34+
#include "device.hpp"
3335
#include "framework/device_dispatch_table.hpp"
3436
#include "framework/device_functions.hpp"
3537
#include "framework/instance_functions.hpp"
@@ -181,3 +183,42 @@ std::vector<std::string> getDeviceExtensionList(VkInstance instance,
181183
* @return the cloned list.
182184
*/
183185
std::vector<const char*> cloneExtensionList(uint32_t extensionCount, const char* const* extensionList);
186+
187+
/**
188+
* Enable VK_KHR_timeline_semaphore if not enabled.
189+
*
190+
* Enabling this requires passing the extension string to vkCreateDevice(),
191+
* and passing either VkPhysicalDeviceTimelineSemaphoreFeatures or
192+
* VkPhysicalDeviceVulkan12Features with the feature enabled.
193+
*
194+
* If the user has the extension enabled but the feature disabled we patch
195+
* their existing structures to enable it.
196+
*
197+
* @param instance The layer instance we are running within.
198+
* @param physicalDevice The physical device we are creating a device for.
199+
* @param createInfo The createInfo we can search to find user config.
200+
* @param supported The list of supported extensions.
201+
*/
202+
void enableDeviceVkKhrTimelineSemaphore(Instance& instance,
203+
VkPhysicalDevice physicalDevice,
204+
vku::safe_VkDeviceCreateInfo& createInfo,
205+
std::vector<std::string>& supported);
206+
207+
/**
208+
* Enable VK_EXT_image_compression_control if not enabled.
209+
*
210+
* Enabling this requires passing the extension string to vkCreateDevice(),
211+
* and passing VkPhysicalDeviceImageCompressionControlFeaturesEXT.
212+
*
213+
* If the user has the extension enabled but the feature disabled we patch
214+
* their existing structures to enable it.
215+
*
216+
* @param instance The layer instance we are running within.
217+
* @param physicalDevice The physical device we are creating a device for.
218+
* @param createInfo The createInfo we can search to find user config.
219+
* @param supported The list of supported extensions.
220+
*/
221+
void enableDeviceVkExtImageCompressionControl(Instance& instance,
222+
VkPhysicalDevice physicalDevice,
223+
vku::safe_VkDeviceCreateInfo& createInfo,
224+
std::vector<std::string>& supported);

0 commit comments

Comments
 (0)