Skip to content

Commit

Permalink
corechecks: Add setting to enable fine-grained locking
Browse files Browse the repository at this point in the history
Add a setting to make calls to ValidationObject::ReadLock() and
WriteLock() be no-ops, because locking in other parts of the code
has made these global locks unnecessary.

Currently this only affects Core Validation, but eventually it should
also change the behavior of Best Practices and Synchronization
Validation.

The setting defaults to off for now and there is logging when fine grained
locking is enabled, since this is an experimental feature which
make cause stability problems or incorrect errors to be reported.
Once this stabilizes, the setting will default to on and the log message
will report when it is turned off, because that will be slow.
  • Loading branch information
jeremyg-lunarg committed Jan 3, 2022
1 parent d23bc29 commit 8de2f06
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 14 deletions.
41 changes: 41 additions & 0 deletions layers/core_validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,53 @@ void CoreChecks::AddInitialLayoutintoImageLayoutMap(const IMAGE_STATE &image_sta
}
}

ReadLockGuard CoreChecks::ReadLock() {
if (fine_grained_locking) {
return ReadLockGuard(validation_object_mutex, std::defer_lock);
} else {
return ReadLockGuard(validation_object_mutex);
}
}

WriteLockGuard CoreChecks::WriteLock() {
if (fine_grained_locking) {
return WriteLockGuard(validation_object_mutex, std::defer_lock);
} else {
return WriteLockGuard(validation_object_mutex);
}
}

// Override base class, we have some extra work to do here
void CoreChecks::InitDeviceValidationObject(bool add_obj, ValidationObject *inst_obj, ValidationObject *dev_obj) {
if (add_obj) {
ValidationStateTracker::InitDeviceValidationObject(add_obj, inst_obj, dev_obj);
}
}

void CoreChecks::PostCallRecordCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
VkInstance *pInstance, VkResult result) {
ValidationStateTracker::PostCallRecordCreateInstance(pCreateInfo, pAllocator, pInstance, result);
if (result == VK_SUCCESS) {
// NOTE: this cannot yet happen in ProcessConfigAndEnvSettings() because this setting is only supported by CoreChecks
std::string locking_string = GetLayerEnvVar("VK_LAYER_FINE_GRAINED_LOCKING");
if (locking_string.empty()) {
locking_string = getLayerOption("khronos_validation.fine_grained_locking");
}
if (!locking_string.empty()) {
transform(locking_string.begin(), locking_string.end(), locking_string.begin(), ::tolower);
if (locking_string == "true") {
fine_grained_locking = true;
} else {
fine_grained_locking = std::atoi(locking_string.c_str()) != 0;
}
}
if (fine_grained_locking) {
LogPerformanceWarning(instance, kVUID_Core_CreateInstance_Locking_Warning,
"Fine-grained locking is expermental, crashes or incorrect results are possible.");
}
}
}

// For given mem object, verify that it is not null or UNBOUND, if it is, report error. Return skip value.
template <typename T1>
bool CoreChecks::VerifyBoundMemoryIsValid(const DEVICE_MEMORY_STATE *mem_state, const T1 object,
Expand Down Expand Up @@ -3168,6 +3208,7 @@ void CoreChecks::PostCallRecordCreateDevice(VkPhysicalDevice gpu, const VkDevice
ValidationObject *device_object = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
ValidationObject *validation_data = GetValidationObject(device_object->object_dispatch, LayerObjectTypeCoreValidation);
CoreChecks *core_checks = static_cast<CoreChecks *>(validation_data);
core_checks->fine_grained_locking = fine_grained_locking;
core_checks->SetSetImageViewInitialLayoutCallback(
[](CMD_BUFFER_STATE *cb_node, const IMAGE_VIEW_STATE &iv_state, VkImageLayout layout) -> void {
cb_node->SetImageViewInitialLayout(iv_state, layout);
Expand Down
20 changes: 14 additions & 6 deletions layers/core_validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,16 +135,15 @@ class CoreChecks : public ValidationStateTracker {
using Struct = core_error::Struct;
using Field = core_error::Field;

GlobalQFOTransferBarrierMap<QFOImageTransferBarrier> qfo_release_image_barrier_map;
GlobalQFOTransferBarrierMap<QFOBufferTransferBarrier> qfo_release_buffer_barrier_map;
GlobalImageLayoutMap imageLayoutMap;
VkValidationCacheEXT core_validation_cache = VK_NULL_HANDLE;
std::string validation_cache_path;

CoreChecks() { container_type = LayerObjectTypeCoreValidation; }

ReadLockGuard ReadLock() override;
WriteLockGuard WriteLock() override;

// Override base class, we have some extra work to do here
void InitDeviceValidationObject(bool add_obj, ValidationObject* inst_obj, ValidationObject* dev_obj) override;
void PostCallRecordCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator,
VkInstance* pInstance, VkResult result) override;

struct SimpleErrorLocation {
const char* func_name;
Expand Down Expand Up @@ -1637,4 +1636,13 @@ class CoreChecks : public ValidationStateTracker {
bool PreCallValidateGetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex,
Display* dpy, VisualID visualID) const override;
#endif // VK_USE_PLATFORM_XLIB_KHR

GlobalQFOTransferBarrierMap<QFOImageTransferBarrier> qfo_release_image_barrier_map;
GlobalQFOTransferBarrierMap<QFOBufferTransferBarrier> qfo_release_buffer_barrier_map;
GlobalImageLayoutMap imageLayoutMap;
VkValidationCacheEXT core_validation_cache = VK_NULL_HANDLE;
std::string validation_cache_path;

private:
bool fine_grained_locking = false;
}; // Class CoreChecks
9 changes: 5 additions & 4 deletions layers/core_validation_error_enums.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* Copyright (c) 2015-2021 The Khronos Group Inc.
* Copyright (c) 2015-2021 Valve Corporation
* Copyright (c) 2015-2021 LunarG, Inc.
* Copyright (C) 2015-2021 Google Inc.
/* Copyright (c) 2015-2022 The Khronos Group Inc.
* Copyright (c) 2015-2022 Valve Corporation
* Copyright (c) 2015-2022 LunarG, Inc.
* Copyright (C) 2015-2022 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -260,6 +260,7 @@ static const char DECORATE_UNUSED *kVUID_Core_CmdBuildAccelNV_NoUpdateMemReqQuer

static const char DECORATE_UNUSED *kVUID_Core_CreatInstance_Status = "UNASSIGNED-khronos-validation-createinstance-status-message";
static const char DECORATE_UNUSED *kVUID_Core_CreateInstance_Debug_Warning = "UNASSIGNED-khronos-Validation-debug-build-warning-message";
static const char DECORATE_UNUSED *kVUID_Core_CreateInstance_Locking_Warning = "UNASSIGNED-khronos-Validation-fine-grained-locking-warning-message";

static const char DECORATE_UNUSED *kVUID_Core_ImageMemoryBarrier_SharingModeExclusiveSameFamily = "UNASSIGNED-CoreValidation-VkImageMemoryBarrier-sharing-mode-exclusive-same-family";
static const char DECORATE_UNUSED *kVUID_Core_ImageMemoryBarrier2_SharingModeExclusiveSameFamily = "UNASSIGNED-CoreValidation-VkImageMemoryBarrier2KHR-sharing-mode-exclusive-same-family";
Expand Down
12 changes: 11 additions & 1 deletion layers/json/VkLayer_khronos_validation.json.in
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,17 @@
}
],
"default": []
}
},
{
"key": "fine_grained_locking",
"env": "VK_LAYER_FINE_GRAINED_LOCKING",
"label": "Enable fine grained locking (Experimental)",
"description": "Enable fine grained locking for Core Validation, which should improve perofrmance in multithreaded applications. This is an experimental feature which may cause stability problems or incorrect errors to be reported.",
"type": "BOOL",
"platforms": [ "WINDOWS", "LINUX", "MACOS", "ANDROID" ],
"default": "false"
}

]
}
}
Expand Down
7 changes: 4 additions & 3 deletions layers/vk_layer_config.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/**************************************************************************
*
* Copyright 2014-2021 Valve Software
* Copyright 2015-2021 Google Inc.
* Copyright 2019-2021 LunarG, Inc.
* Copyright 2014-2022 Valve Software
* Copyright 2015-2022 Google Inc.
* Copyright 2019-2022 LunarG, Inc.
* All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -187,6 +187,7 @@ ConfigFile::ConfigFile() : file_is_parsed_(false) {
value_map_["khronos_validation.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG";
#endif // WIN32
value_map_["khronos_validation.log_filename"] = "stdout";
value_map_["khronos_validation.fine_grained_locking"] = "false";
}

const char *ConfigFile::GetOption(const string &option) {
Expand Down
1 change: 1 addition & 0 deletions layers/vk_layer_settings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,5 @@ khronos_validation.log_filename = stdout
# Example of how to redirect debug printf messages from the debug callback to stdout
#khronos_validation.printf_to_stdout = true

#khronos_validation.fine_grained_locking = false
################################################################################

0 comments on commit 8de2f06

Please sign in to comment.