Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

layer: Add minimum setting reflection #61

Merged
merged 1 commit into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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