Skip to content

Commit

Permalink
layer: Add minimum setting reflection
Browse files Browse the repository at this point in the history
  • Loading branch information
christophe-lunarg committed Aug 15, 2023
1 parent 79d5fb1 commit ed2d4d1
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 51 deletions.
9 changes: 6 additions & 3 deletions include/vulkan/layer/vk_layer_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ extern "C" {

VK_DEFINE_HANDLE(VlLayerSettingSet)

typedef void *(*VL_LAYER_SETTING_LOG_CALLBACK)(const char *pSettingName, const char *pMessage);
typedef void (VKAPI_PTR *VlLayerSettingLogCallback)(const char *pSettingName, const char *pMessage);

void vlRegistryLayerSettingsProperties(const char *pLayerName,
uint32_t propertyCount, VkLayerSettingPropertiesEXT *pProperties);

// Create a layer setting set. If 'pCallback' is set to NULL, the messages are outputed to stderr.
VkResult vlCreateLayerSettingSet(const char *pLayerName, const VkLayerSettingsCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VL_LAYER_SETTING_LOG_CALLBACK pCallback, VlLayerSettingSet *pLayerSettingSet);
const VkAllocationCallbacks *pAllocator, VlLayerSettingLogCallback pCallback,
VlLayerSettingSet *pLayerSettingSet);

void vlDestroyLayerSettingSet(VlLayerSettingSet layerSettingSet, const VkAllocationCallbacks *pAllocator);

Expand Down
51 changes: 11 additions & 40 deletions include/vulkan/layer/vk_layer_settings_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,53 +15,14 @@ extern "C" {

#include <vulkan/vk_layer.h>

// VK_EXT_layer_settings
//
// Name String
// VK_EXT_layer_settings
//
// Extension Type
// Instance extension
//
// Revision
// 1
//
// Extension and Version Dependencies
// Requires Vulkan 1.0
//
// Contact
// Christophe Riccio christophe-lunarg
//
// Contributors
// Christophe Riccio
// Mark Lobodzinski
//
// Description
// This extension provides a mechanism for configuring programmatically through
// the Vulkan API the behavior of layers.
//
// This extension provides the [VkLayerSettingsCreateInfoEXT] struct that can be
// included in the [pNext] chain of the [VkInstanceCreateInfo]
// structure passed as the [pCreateInfo] parameter of [vkCreateInstance].
//
// The structure contains an array of [VkLayerSettingEXT] structure
// values that configure specific features of layers.
//
// Note
// The [VK_EXT_layer_settings] extension subsumes all the functionality provided in the [VK_EXT_validation_flags] extension
// and the [VK_EXT_validation_features] extension.

#define VK_EXT_layer_settings 1
#define VK_EXT_LAYER_SETTINGS_SPEC_VERSION 1
#define VK_EXT_LAYER_SETTINGS_EXTENSION_NAME "VK_EXT_layer_settings"

// This extension is exclusively used by VVL, and is NOT intended as a deliverable.
// The value of the VK_STRUCTURE_TYPE is arbitrary. The only requirement,
// is that it must not conflict with existing sTypes.
//
// NOTE: VK_STRUCTURE_TYPE_MAX_ENUM - 1 is used by the intel driver.
// NOTE: VK_STRUCTURE_TYPE_MAX_ENUM - 42 is used by the validation layers
#define VK_STRUCTURE_TYPE_LAYER_SETTINGS_EXT ((VkStructureType)(VK_STRUCTURE_TYPE_MAX_ENUM - 43))
#define VK_STRUCTURE_TYPE_LAYER_SETTING_PROPERTIES_EXT ((VkStructureType)(VK_STRUCTURE_TYPE_MAX_ENUM - 44))

typedef enum VkLayerSettingTypeEXT {
VK_LAYER_SETTING_TYPE_BOOL32_EXT = 0,
Expand Down Expand Up @@ -96,6 +57,16 @@ typedef struct VkLayerSettingsCreateInfoEXT {
const VkLayerSettingEXT *pSettings;
} VkLayerSettingsCreateInfoEXT;

typedef struct VkLayerSettingPropertiesEXT {
VkStructureType sType;
const void *pNext;
char key[VK_MAX_DESCRIPTION_SIZE];
VkLayerSettingTypeEXT type;
} VkLayerSettingPropertiesEXT;

VkResult vkEnumerateInstanceLayerSettingsEXT(const char *pLayerName,
uint32_t *pPropertyCount, VkLayerSettingPropertiesEXT *pProperties);

#ifdef __cplusplus
}
#endif
1 change: 1 addition & 0 deletions src/layer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ target_compile_features(VulkanLayerSettings PRIVATE cxx_std_17)
target_sources(VulkanLayerSettings PRIVATE
vk_layer_settings.cpp
vk_layer_settings_helper.cpp
vk_layer_settings_interface.cpp
layer_settings_manager.cpp
layer_settings_manager.hpp
layer_settings_util.cpp
Expand Down
8 changes: 4 additions & 4 deletions src/layer/layer_settings_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ static void AddWorkaroundLayerNames(std::vector<std::string> &layer_names) {
namespace vl {

LayerSettings::LayerSettings(const char *pLayerName, const VkLayerSettingsCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VL_LAYER_SETTING_LOG_CALLBACK callback)
: layer_name(pLayerName), create_info(pCreateInfo), callback(callback) {
const VkAllocationCallbacks *pAllocator, VlLayerSettingLogCallback pCallback)
: layer_name(pLayerName), create_info(pCreateInfo), pCallback(pCallback) {
(void)pAllocator;
assert(pLayerName != nullptr);

Expand Down Expand Up @@ -243,10 +243,10 @@ void LayerSettings::Log(const char *pSettingName, const char * pMessage) {
this->last_log_setting = pSettingName;
this->last_log_message = pMessage;

if (this->callback == nullptr) {
if (this->pCallback == nullptr) {
fprintf(stderr, "LAYER SETTING (%s) error: %s\n", this->last_log_setting.c_str(), this->last_log_message.c_str());
} else {
this->callback(this->last_log_setting.c_str(), this->last_log_message.c_str());
this->pCallback(this->last_log_setting.c_str(), this->last_log_message.c_str());
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/layer/layer_settings_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace vl {
class LayerSettings {
public:
LayerSettings(const char *pLayerName, const VkLayerSettingsCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VL_LAYER_SETTING_LOG_CALLBACK callback);
const VkAllocationCallbacks *pAllocator, VlLayerSettingLogCallback pCallback);
~LayerSettings();

bool HasEnvSetting(const char *pSettingName);
Expand Down Expand Up @@ -53,7 +53,7 @@ namespace vl {

std::string layer_name;
const VkLayerSettingsCreateInfoEXT *create_info{nullptr};
VL_LAYER_SETTING_LOG_CALLBACK callback{nullptr};
VlLayerSettingLogCallback pCallback{nullptr};
};
}// namespace vl

9 changes: 8 additions & 1 deletion src/layer/vk_layer_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@
#include <cctype>
#include <cstring>
#include <cstdint>
#include <unordered_map>

std::unordered_map<std::string, std::pair<uint32_t, VkLayerSettingPropertiesEXT *> > layer_settings_properties;

void vlRegistryLayerSettingsProperties(const char *pLayerName, uint32_t propertyCount, VkLayerSettingPropertiesEXT *pProperties) {
layer_settings_properties.insert(std::pair(pLayerName, std::pair(propertyCount, pProperties)));
}

// This is used only for unit tests in test_layer_setting_file
void test_helper_SetLayerSetting(VlLayerSettingSet layerSettingSet, const char *pSettingName, const char *pValue) {
Expand All @@ -30,7 +37,7 @@ void test_helper_SetLayerSetting(VlLayerSettingSet layerSettingSet, const char *
}

VkResult vlCreateLayerSettingSet(const char *pLayerName, const VkLayerSettingsCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VL_LAYER_SETTING_LOG_CALLBACK pCallback,
const VkAllocationCallbacks *pAllocator, VlLayerSettingLogCallback pCallback,
VlLayerSettingSet *pLayerSettingSet) {
(void)pAllocator;

Expand Down
42 changes: 42 additions & 0 deletions src/layer/vk_layer_settings_interface.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2023 The Khronos Group Inc.
// Copyright 2023 Valve Corporation
// Copyright 2023 LunarG, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
// Author(s):
// - Christophe Riccio <christophe@lunarg.com>

#include "vulkan/layer/vk_layer_settings_ext.h"
#include <cassert>
#include <cstring>
#include <string>
#include <unordered_map>

#if defined(__GNUC__) && __GNUC__ >= 4
#define LAYER_EXPORT __attribute__((visibility("default")))
#else
#define LAYER_EXPORT
#endif

extern std::unordered_map<std::string, std::pair<uint32_t, VkLayerSettingPropertiesEXT*> > layer_settings_properties;

// Keep synchronized with VkLayer_khronos_profiles.def / VkLayer_khronos_profiles.map
extern "C" {

LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerSettingsEXT(
const char* pLayerName, uint32_t* pPropertyCount, VkLayerSettingPropertiesEXT* pProperties) {

assert(pPropertyCount != nullptr);

if (*pPropertyCount > 0 && pProperties != nullptr) {
*pPropertyCount = std::min(*pPropertyCount, layer_settings_properties[pLayerName].first);
memcpy(pProperties, layer_settings_properties[pLayerName].second, sizeof(VkLayerSettingPropertiesEXT) * *pPropertyCount);
} else {
*pPropertyCount = layer_settings_properties[pLayerName].first;
}

return VK_SUCCESS;
}

} // extern "C"
29 changes: 28 additions & 1 deletion tests/layer/test_setting_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,34 @@
#include <gtest/gtest.h>

#include "vulkan/layer/vk_layer_settings.h"
#include <vector>

TEST(test_layer_setting_api, vkEnumerateInstanceLayerSettingsEXT) {

VkLayerSettingPropertiesEXT properties[] = {
{VK_STRUCTURE_TYPE_LAYER_SETTING_PROPERTIES_EXT, nullptr, "settingA", VK_LAYER_SETTING_TYPE_BOOL32_EXT},
{VK_STRUCTURE_TYPE_LAYER_SETTING_PROPERTIES_EXT, nullptr, "settingB", VK_LAYER_SETTING_TYPE_UINT32_EXT}
};

vlRegistryLayerSettingsProperties("VK_LAYER_LUNARG_test", static_cast<uint32_t>(std::size(properties)), &properties[0]);

uint32_t result_count = 0;
vkEnumerateInstanceLayerSettingsEXT("VK_LAYER_LUNARG_test", &result_count, nullptr);

EXPECT_EQ(static_cast<uint32_t>(std::size(properties)), result_count);

std::vector<VkLayerSettingPropertiesEXT> results(static_cast<std::size_t>(result_count));
vkEnumerateInstanceLayerSettingsEXT("VK_LAYER_LUNARG_test", &result_count, &results[0]);

EXPECT_EQ(properties[0].sType, results[0].sType);
EXPECT_EQ(properties[0].pNext, results[0].pNext);
EXPECT_STREQ(properties[0].key, results[0].key);
EXPECT_EQ(properties[0].type, results[0].type);

EXPECT_EQ(properties[1].sType, results[1].sType);
EXPECT_EQ(properties[1].pNext, results[1].pNext);
EXPECT_STREQ(properties[1].key, results[1].key);
EXPECT_EQ(properties[1].type, results[1].type);
}

TEST(test_layer_setting_api, vlHasLayerSetting_NotFound) {
VlLayerSettingSet layerSettingSet = VK_NULL_HANDLE;
Expand Down

0 comments on commit ed2d4d1

Please sign in to comment.