Skip to content

Commit

Permalink
layers: Add layer settings library
Browse files Browse the repository at this point in the history
  • Loading branch information
christophe-lunarg committed Aug 29, 2023
1 parent 6ac5fcb commit c87dc58
Show file tree
Hide file tree
Showing 23 changed files with 166 additions and 809 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ else()
endif()
endif()

find_package(VulkanUtilityLibraries CONFIG REQUIRED)

option(BUILD_WERROR "Treat compiler warnings as errors")
if (BUILD_WERROR)
add_compile_options("$<IF:$<CXX_COMPILER_ID:MSVC>,/WX,-Werror>")
Expand Down
2 changes: 1 addition & 1 deletion layers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ endif()
foreach(extension_layer ${EXTENSION_LAYERS})
target_include_directories(${extension_layer} PRIVATE .)

target_link_libraries(${extension_layer} PRIVATE VkExtLayer_utils)
target_link_libraries(${extension_layer} PRIVATE VkExtLayer_utils Vulkan::LayerSettings)

if(MSVC)
target_link_options(${extension_layer} PRIVATE /DEF:${CMAKE_CURRENT_SOURCE_DIR}/${extension_layer}.def)
Expand Down
6 changes: 3 additions & 3 deletions layers/VkLayer_khronos_synchronization2.def
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

;;;; Begin Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Copyright (c) 2015-2021 The Khronos Group Inc.
; Copyright (c) 2015-2021 Valve Corporation
; Copyright (c) 2015-2021 LunarG, Inc.
; Copyright (c) 2015-2023 The Khronos Group Inc.
; Copyright (c) 2015-2023 Valve Corporation
; Copyright (c) 2015-2023 LunarG, Inc.
; Copyright (c) 2020 Intel Corporation
;
; Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
6 changes: 3 additions & 3 deletions layers/VkLayer_khronos_timeline_semaphore.def
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

;;;; Begin Copyright Notice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Copyright (c) 2015-2019, 2021 The Khronos Group Inc.
; Copyright (c) 2015-2019, 2021 Valve Corporation
; Copyright (c) 2015-2019, 2021 LunarG, Inc.
; Copyright (c) 2015-2023 The Khronos Group Inc.
; Copyright (c) 2015-2023 Valve Corporation
; Copyright (c) 2015-2023 LunarG, Inc.
; Copyright (c) 2020 Intel Corporation
;
; Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
103 changes: 29 additions & 74 deletions layers/decompression/decompression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ static bool logging_enabled = false;
}

#include <vulkan/vk_layer.h>
#include <vulkan/layer/vk_layer_settings.hpp>
#include "allocator.h"
#include "log.h"
#include "vk_layer_config.h"
#include "vk_safe_struct.h"
#include "vk_util.h"
#include "decompression.h"
Expand Down Expand Up @@ -115,6 +115,10 @@ static const ByteCode kIndirectGInflateBytecode[] = {
{(const uint8_t*)kIndirectGInflate64_HAVE_INT16_HAVE_INT64, sizeof(kIndirectGInflate64_HAVE_INT16_HAVE_INT64)},
};

#define kLayerSettingsForceEnable "force_device"
#define kLayerSettingsCustomSTypeInfo "custom_stype_list"
#define kLayerSettingsLogging "logging"

// required by vk_safe_struct
std::vector<std::pair<uint32_t, uint32_t>> custom_stype_info{};

Expand All @@ -130,65 +134,9 @@ static const VkLayerProperties kGlobalLayer = {
static const VkExtensionProperties kDeviceExtension = {VK_NV_MEMORY_DECOMPRESSION_EXTENSION_NAME,
VK_NV_MEMORY_DECOMPRESSION_SPEC_VERSION};

static const char* const kEnvarForceEnable =
#if defined(__ANDROID__)
"debug.vulkan.memory_decompression.force_enable";
#else
"VK_MEMORY_DECOMPRESSION_FORCE_ENABLE";
#endif
static const char* const kLayerSettingsForceEnable = "khronos_memory_decompression.force_enable";

static const char* const kEnvarLogging =
#if defined(__ANDROID__)
"debug.vulkan.memory_decompression.logging";
#else
"VK_MEMORY_DECOMPRESSION_LOGGING";
#endif
static const char* const kLayerSettingsLogging = "khronos_memory_decompression.logging";

static vl_concurrent_unordered_map<uintptr_t, std::shared_ptr<InstanceData>> instance_data_map;
static vl_concurrent_unordered_map<uintptr_t, std::shared_ptr<DeviceData>> device_data_map;

static void string_tolower(std::string& s) {
for (auto& c : s) {
c = tolower(c);
}
}

static bool GetForceEnable() {
bool result = false;
std::string setting = GetEnvironment(kEnvarForceEnable);
if (setting.empty()) {
setting = GetLayerOption(kLayerSettingsForceEnable);
}
if (!setting.empty()) {
string_tolower(setting);
if (setting == "true") {
result = true;
} else {
result = std::atoi(setting.c_str()) != 0;
}
}
return result;
}

static bool GetLoggingEnabled() {
bool result = false;
std::string setting = GetEnvironment(kEnvarLogging);
if (setting.empty()) {
setting = GetLayerOption(kLayerSettingsLogging);
}
if (!setting.empty()) {
string_tolower(setting);
if (setting == "true") {
result = true;
} else {
result = std::atoi(setting.c_str()) != 0;
}
}
return result;
}

uintptr_t DispatchKey(const void* object) {
auto tmp = reinterpret_cast<const struct VkLayerDispatchTable_* const*>(object);
return reinterpret_cast<uintptr_t>(*tmp);
Expand Down Expand Up @@ -274,7 +222,7 @@ VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalD

#define INIT_HOOK(_vt, _inst, fn) _vt.fn = reinterpret_cast<PFN_vk##fn>(vtable.GetInstanceProcAddr(_inst, "vk" #fn))
InstanceData::InstanceData(VkInstance inst, PFN_vkGetInstanceProcAddr gpa, const VkAllocationCallbacks* alloc)
: instance(inst), api_version(0), force_enable(false), allocator(alloc) {
: instance(inst), api_version(0), allocator(alloc) {
vtable.GetInstanceProcAddr = gpa;
INIT_HOOK(vtable, instance, CreateInstance);
INIT_HOOK(vtable, instance, DestroyInstance);
Expand All @@ -297,18 +245,25 @@ static VkLayerInstanceCreateInfo* GetChainInfo(const VkInstanceCreateInfo* pCrea
return chain_info;
}

// Get all elements from a vkEnumerate*() lambda into a std::vector.
template <typename T>
VkResult EnumerateAll(std::vector<T>* vect, std::function<VkResult(uint32_t*, T*)> func) {
VkResult result = VK_INCOMPLETE;
do {
uint32_t count = 0;
result = func(&count, nullptr);
ASSERT(result == VK_SUCCESS);
vect->resize(count);
result = func(&count, vect->data());
} while (result == VK_INCOMPLETE);
return result;
void InitLayerSettings(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, LayerSettings* layer_settings) {
assert(layer_settings != nullptr);

VlLayerSettingSet layerSettingSet = VK_NULL_HANDLE;
vlCreateLayerSettingSet(kGlobalLayer.layerName, vlFindLayerSettingsCreateInfo(pCreateInfo), pAllocator, nullptr, &layerSettingSet);

if (vlHasLayerSetting(layerSettingSet, kLayerSettingsForceEnable)) {
vlGetLayerSettingValue(layerSettingSet, kLayerSettingsForceEnable, layer_settings->force_enable);
}

if (vlHasLayerSetting(layerSettingSet, kLayerSettingsLogging)) {
vlGetLayerSettingValue(layerSettingSet, kLayerSettingsLogging, layer_settings->logging);
}

if (vlHasLayerSetting(layerSettingSet, kLayerSettingsCustomSTypeInfo)) {
vlGetLayerSettingValues(layerSettingSet, kLayerSettingsCustomSTypeInfo, custom_stype_info);
}

vlDestroyLayerSettingSet(layerSettingSet, pAllocator);
}

VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator,
Expand All @@ -322,8 +277,6 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo* pCreat
return VK_ERROR_INITIALIZATION_FAILED;
}

logging_enabled = GetLoggingEnabled();

// Advance the link info for the next element on the chain
chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;

Expand All @@ -337,8 +290,10 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo* pCreat

instance_data_map.insert(DispatchKey(*pInstance), instance_data);

instance_data->force_enable = GetForceEnable();
instance_data->api_version = pCreateInfo->pApplicationInfo ? pCreateInfo->pApplicationInfo->apiVersion : 0;

InitLayerSettings(pCreateInfo, pAllocator, &instance_data->layer_settings);
logging_enabled = instance_data->layer_settings.logging;
} catch (const std::bad_alloc&) {
auto destroy_instance = reinterpret_cast<PFN_vkDestroyInstance>(gpa(NULL, "vkDestroyInstance"));
destroy_instance(*pInstance, pAllocator);
Expand Down Expand Up @@ -749,7 +704,7 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice physicalDevice, con
PRINT("Memory decompression feature not available in the driver, enabling decompression layer.\n");
enable_layer = true;
} else {
if (instance_data->force_enable) {
if (instance_data->layer_settings.force_enable) {
PRINT("Memory decompression feature available in the driver, but force enabling decompression layer.\n");
enable_layer = true;
} else {
Expand Down
7 changes: 6 additions & 1 deletion layers/decompression/decompression.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ enum class SynchronizationScope { kFirst, kSecond };
struct DeviceData;
struct DeviceFeatures;

struct LayerSettings {
bool force_enable{false};
bool logging{false};
};

template <typename T>
using CmdVector = std::vector<T, extension_layer::CmdAlloc<T>>;

Expand Down Expand Up @@ -74,7 +79,7 @@ struct InstanceData {

VkInstance instance;
uint32_t api_version;
bool force_enable;
LayerSettings layer_settings;
const VkAllocationCallbacks* allocator;
struct InstanceDispatchTable {
DECLARE_HOOK(GetInstanceProcAddr);
Expand Down
62 changes: 29 additions & 33 deletions layers/shader_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@

#include <vulkan/vulkan.h>
#include <vulkan/vk_layer.h>
#include <vulkan/layer/vk_layer_settings.hpp>

#include "log.h"
#include "vk_safe_struct.h"
#include "vk_api_hash.h"
#include "vk_layer_config.h"

#define kLayerSettingsForceEnable "force_device"
#define kLayerSettingsCustomSTypeInfo "custom_stype_list"

// Required by vk_safe_struct
std::vector<std::pair<uint32_t, uint32_t>> custom_stype_info{};
Expand Down Expand Up @@ -80,37 +83,6 @@ namespace shader_object {
static const char* kLayerName = "VK_LAYER_KHRONOS_shader_object";
static const VkExtensionProperties kExtensionProperties = {VK_EXT_SHADER_OBJECT_EXTENSION_NAME, VK_EXT_SHADER_OBJECT_SPEC_VERSION};

static const char* const kEnvarForceEnable =
#if defined(__ANDROID__)
"debug.vulkan.shader_object.force_enable";
#else
"VK_SHADER_OBJECT_FORCE_ENABLE";
#endif
static const char* const kLayerSettingsForceEnable = "khronos_shader_object.force_enable";

static void string_tolower(std::string &s) {
for (auto& c: s) {
c = tolower(c);
}
}

static bool GetForceEnable() {
bool result = false;
std::string setting = GetEnvironment(kEnvarForceEnable);
if (setting.empty()) {
setting = GetLayerOption(kLayerSettingsForceEnable);
}
if (!setting.empty()) {
string_tolower(setting);
if (setting == "true") {
result = true;
} else {
result = std::atoi(setting.c_str()) != 0;
}
}
return result;
}

class AlignedMemory {
public:
AlignedMemory() : size_(0), max_alignment_(1), memory_write_ptr_(nullptr) {}
Expand Down Expand Up @@ -1219,11 +1191,16 @@ class CommandBufferData {
FullDrawStateData* draw_state_data_;
};

struct LayerSettings {
bool force_enable{false};
};

struct InstanceData {
LayerDispatchInstance vtable;
VkInstance instance;
VkPhysicalDevice* physical_devices;
uint32_t physical_device_count;
LayerSettings layer_settings;
};

struct PhysicalDeviceData {
Expand Down Expand Up @@ -2610,6 +2587,23 @@ static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance i

static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char* pName);

void InitLayerSettings(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, LayerSettings* layer_settings) {
assert(layer_settings != nullptr);

VlLayerSettingSet layerSettingSet = VK_NULL_HANDLE;
vlCreateLayerSettingSet(kLayerName, vlFindLayerSettingsCreateInfo(pCreateInfo), pAllocator, nullptr, &layerSettingSet);

if (vlHasLayerSetting(layerSettingSet, kLayerSettingsForceEnable)) {
vlGetLayerSettingValue(layerSettingSet, kLayerSettingsForceEnable, layer_settings->force_enable);
}

if (vlHasLayerSetting(layerSettingSet, kLayerSettingsCustomSTypeInfo)) {
vlGetLayerSettingValues(layerSettingSet, kLayerSettingsCustomSTypeInfo, custom_stype_info);
}

vlDestroyLayerSettingSet(layerSettingSet, pAllocator);
}

static VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) {
auto allocator = pAllocator ? *pAllocator : kDefaultAllocator;
Expand Down Expand Up @@ -2653,6 +2647,8 @@ static VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo*
instance_data->physical_device_count = physical_device_count;
instance_data->vtable.Initialize(*pInstance, fpGetInstanceProcAddr);

InitLayerSettings(pCreateInfo, pAllocator, &instance_data->layer_settings);

result = fpEnumeratePhysicalDevices(*pInstance, &instance_data->physical_device_count, instance_data->physical_devices);
ASSERT(result == VK_SUCCESS);

Expand Down Expand Up @@ -2917,7 +2913,7 @@ static VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice physicalDevi
// only enable the layer if the application asked for the extension and feature AND the driver does not have a native
// implementation (unless if the user specified to ignore the native implementation via environment variable)
bool enable_layer = shader_object_feature_requested && shader_object_extension_requested;
bool ignore_native_implementation = GetForceEnable();
bool ignore_native_implementation = instance_data->layer_settings.force_enable;
if (ignore_native_implementation) {
DEBUG_LOG("ignoring native driver implementation of shader object\n");
}
Expand Down
Loading

0 comments on commit c87dc58

Please sign in to comment.