From 0ea4f89595e6f4df6a2b94563ceed124a66793c3 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Sat, 7 Dec 2024 15:15:25 +0100 Subject: [PATCH] feat: move nsight aftermath to module ( Silverlan/pr_nsight_aftermath ) --- build_scripts/build.py | 11 +- build_scripts/scripts/external_libs.py | 2 +- build_scripts/scripts/modules.py | 2 +- .../include/pragma/debug/nsight_aftermath.hpp | 211 ----------- core/client/src/c_engine.cpp | 6 - core/client/src/debug/nsight_aftermath.cpp | 327 ------------------ .../client/src/rendering/c_render_context.cpp | 12 +- 7 files changed, 21 insertions(+), 550 deletions(-) delete mode 100644 core/client/include/pragma/debug/nsight_aftermath.hpp delete mode 100644 core/client/src/debug/nsight_aftermath.cpp diff --git a/build_scripts/build.py b/build_scripts/build.py index 5c34fe91b..bb6d35ec7 100644 --- a/build_scripts/build.py +++ b/build_scripts/build.py @@ -767,7 +767,8 @@ def execbuildscript(filepath): "execbuildscript": execbuildscript, "str2bool": str2bool, "install_prebuilt_binaries": install_prebuilt_binaries, - "reset_to_commit": reset_to_commit + "reset_to_commit": reset_to_commit, + "add_pragma_module": add_pragma_module } if platform == "linux": l["c_compiler"] = c_compiler @@ -820,7 +821,7 @@ def execbuildscript(filepath): if with_essential_client_modules: add_pragma_module( name="pr_prosper_vulkan", - commitSha="1cab6a2cc1cfb5ab3f5e45e0b454d9638ef3e87f", + commitSha="b878be11c48f9b6e11fae8b4395b3ba78551569b", repositoryUrl="https://github.com/Silverlan/pr_prosper_vulkan.git" ) @@ -914,7 +915,10 @@ def execbuildscript(filepath): # CMake configuration explicitly if they should be disabled. shippedModules = ["pr_audio_dummy","pr_prosper_opengl","pr_prosper_vulkan","pr_curl"] -for module in module_info: +index = 0 +# The module list can be modified during iteration, so we have to use a while loop here. +while index < len(module_info): + module = module_info[index] global moduleName moduleName = module["name"] moduleUrl = module["repositoryUrl"] @@ -945,6 +949,7 @@ def execbuildscript(filepath): if not skipBuildTarget: module_list.append(moduleName) + index += 1 for module in shippedModules: if module != "pr_curl": # Curl is currently required diff --git a/build_scripts/scripts/external_libs.py b/build_scripts/scripts/external_libs.py index 9df4b4d28..e597ae880 100644 --- a/build_scripts/scripts/external_libs.py +++ b/build_scripts/scripts/external_libs.py @@ -16,7 +16,7 @@ get_submodule("mathutil","https://github.com/Silverlan/mathutil.git","e872f599805cf696ff6a84a4253fc44ae8e83a15") get_submodule("networkmanager","https://github.com/Silverlan/networkmanager.git","981bc5809c1a768267ddace778205e1be0262730") get_submodule("panima","https://github.com/Silverlan/panima.git","06916dd30cde319f31b1eee25cfed7dea8f14630") -get_submodule("prosper","https://github.com/Silverlan/prosper.git","c38390b43d2072bf0a9507d4218ea35b7af4785d") +get_submodule("prosper","https://github.com/Silverlan/prosper.git","958b514432224057fb9af6d530eeaeb236cd3656") get_submodule("sharedutils","https://github.com/Silverlan/sharedutils.git","65031009e7f85722f243a493ad47e03ca10617fe") get_submodule("util_bsp","https://github.com/Silverlan/util_bsp.git","2d912cceaaa59199a86431aa9d194e922b2ebea4") get_submodule("util_formatted_text","https://github.com/Silverlan/util_formatted_text.git","c473a2bdc1ad84ef52d391226d6983ef3076958e") diff --git a/build_scripts/scripts/modules.py b/build_scripts/scripts/modules.py index 9517a0c8d..964e33c6c 100644 --- a/build_scripts/scripts/modules.py +++ b/build_scripts/scripts/modules.py @@ -12,6 +12,6 @@ get_submodule("pr_audio_dummy","https://github.com/Silverlan/pr_audio_dummy.git","1a806a1a7b2283bd8551d07e4f1d680499f68b90") get_submodule("pr_curl","https://github.com/Silverlan/pr_curl.git","974c67cc76710809a9595fcfbc4167554799cd7f") get_submodule("pr_prosper_opengl","https://github.com/Silverlan/pr_prosper_opengl.git","9cf6bc0b8b26cbd044c2e202dc9be57cc87e7e1b") -get_submodule("pr_prosper_vulkan","https://github.com/Silverlan/pr_prosper_vulkan.git","1cab6a2cc1cfb5ab3f5e45e0b454d9638ef3e87f") +get_submodule("pr_prosper_vulkan","https://github.com/Silverlan/pr_prosper_vulkan.git","b878be11c48f9b6e11fae8b4395b3ba78551569b") os.chdir(curDir) diff --git a/core/client/include/pragma/debug/nsight_aftermath.hpp b/core/client/include/pragma/debug/nsight_aftermath.hpp deleted file mode 100644 index d999305a9..000000000 --- a/core/client/include/pragma/debug/nsight_aftermath.hpp +++ /dev/null @@ -1,211 +0,0 @@ -//********************************************************* -// -// Copyright (c) 2019-2022, NVIDIA CORPORATION. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -//********************************************************* - -#pragma once - -// See the following for more information: -// https://github.com/NVIDIA/nsight-aftermath-samples/tree/master/VkHelloNsightAftermath -// https://developer.nvidia.com/nsight-aftermath - -// #define PRAGMA_ENABLE_NSIGHT_AFTERMATH -#ifdef PRAGMA_ENABLE_NSIGHT_AFTERMATH - -// #define NSIGHT_ENABLE_SHADER_DATABASE - -#include "pragma/clientdefinitions.h" -#include -#include -#include -#include -#include -#include -#include -#include - -//********************************************************* -// Some std::to_string overloads for some Nsight Aftermath -// API types. -// - -namespace std { - template - inline std::string to_hex_string(T n) - { - std::stringstream stream; - stream << std::setfill('0') << std::setw(2 * sizeof(T)) << std::hex << n; - return stream.str(); - } - - inline std::string to_string(GFSDK_Aftermath_Result result) { return std::string("0x") + to_hex_string(static_cast(result)); } - - inline std::string to_string(const GFSDK_Aftermath_ShaderDebugInfoIdentifier &identifier) { return to_hex_string(identifier.id[0]) + "-" + to_hex_string(identifier.id[1]); } - - inline std::string to_string(const GFSDK_Aftermath_ShaderBinaryHash &hash) { return to_hex_string(hash.hash); } -} // namespace std - -inline std::string AftermathErrorMessage(GFSDK_Aftermath_Result result) -{ - switch(result) { - case GFSDK_Aftermath_Result_FAIL_DriverVersionNotSupported: - return "Unsupported driver version - requires an NVIDIA R495 display driver or newer."; - default: - return "Aftermath Error 0x" + std::to_hex_string(result); - } -} - -// Helper macro for checking Nsight Aftermath results and throwing exception -// in case of a failure. -#ifdef _WIN32 -#define AFTERMATH_CHECK_ERROR(FC) \ - [&]() { \ - GFSDK_Aftermath_Result _result = FC; \ - if(!GFSDK_Aftermath_SUCCEED(_result)) { \ - MessageBoxA(0, AftermathErrorMessage(_result).c_str(), "Aftermath Error", MB_OK); \ - exit(1); \ - } \ - }() -#else -#define AFTERMATH_CHECK_ERROR(FC) \ - [&]() { \ - GFSDK_Aftermath_Result _result = FC; \ - if(!GFSDK_Aftermath_SUCCEED(_result)) { \ - printf("%s\n", AftermathErrorMessage(_result).c_str()); \ - fflush(stdout); \ - exit(1); \ - } \ - }() -#endif - -// Helper for comparing GFSDK_Aftermath_ShaderDebugInfoIdentifier. -inline bool operator<(const GFSDK_Aftermath_ShaderDebugInfoIdentifier &lhs, const GFSDK_Aftermath_ShaderDebugInfoIdentifier &rhs) -{ - if(lhs.id[0] == rhs.id[0]) { - return lhs.id[1] < rhs.id[1]; - } - return lhs.id[0] < rhs.id[0]; -} - -//********************************************************* -// Implements GPU crash dump tracking using the Nsight -// Aftermath API. -// -class GpuCrashTracker { - public: - // keep four frames worth of marker history - const static unsigned int c_markerFrameHistory = 4; - typedef std::array, c_markerFrameHistory> MarkerMap; - - GpuCrashTracker(const MarkerMap &markerMap); - ~GpuCrashTracker(); - - // Initialize the GPU crash dump tracker. - void Initialize(); - private: - //********************************************************* - // Callback handlers for GPU crash dumps and related data. - // - - // Handler for GPU crash dump callbacks. - void OnCrashDump(const void *pGpuCrashDump, const uint32_t gpuCrashDumpSize); - - // Handler for shader debug information callbacks. - void OnShaderDebugInfo(const void *pShaderDebugInfo, const uint32_t shaderDebugInfoSize); - - // Handler for GPU crash dump description callbacks. - void OnDescription(PFN_GFSDK_Aftermath_AddGpuCrashDumpDescription addDescription); - - // Handler for app-managed marker resolve callback - void OnResolveMarker(const void *pMarker, void **resolvedMarkerData, uint32_t *markerSize); - - //********************************************************* - // Helpers for writing a GPU crash dump and debug information - // data to files. - // - - // Helper for writing a GPU crash dump to a file. - void WriteGpuCrashDumpToFile(const void *pGpuCrashDump, const uint32_t gpuCrashDumpSize); - - // Helper for writing shader debug information to a file - void WriteShaderDebugInformationToFile(GFSDK_Aftermath_ShaderDebugInfoIdentifier identifier, const void *pShaderDebugInfo, const uint32_t shaderDebugInfoSize); - - //********************************************************* - // Helpers for decoding GPU crash dump to JSON. - // - - // Handler for shader debug info lookup callbacks. - void OnShaderDebugInfoLookup(const GFSDK_Aftermath_ShaderDebugInfoIdentifier &identifier, PFN_GFSDK_Aftermath_SetData setShaderDebugInfo) const; - - // Handler for shader lookup callbacks. - void OnShaderLookup(const GFSDK_Aftermath_ShaderBinaryHash &shaderHash, PFN_GFSDK_Aftermath_SetData setShaderBinary) const; - - // Handler for shader source debug info lookup callbacks. - void OnShaderSourceDebugInfoLookup(const GFSDK_Aftermath_ShaderDebugName &shaderDebugName, PFN_GFSDK_Aftermath_SetData setShaderBinary) const; - - //********************************************************* - // Static callback wrappers. - // - - // GPU crash dump callback. - static void GpuCrashDumpCallback(const void *pGpuCrashDump, const uint32_t gpuCrashDumpSize, void *pUserData); - - // Shader debug information callback. - static void ShaderDebugInfoCallback(const void *pShaderDebugInfo, const uint32_t shaderDebugInfoSize, void *pUserData); - - // GPU crash dump description callback. - static void CrashDumpDescriptionCallback(PFN_GFSDK_Aftermath_AddGpuCrashDumpDescription addDescription, void *pUserData); - - // App-managed marker resolve callback - static void ResolveMarkerCallback(const void *pMarker, void *pUserData, void **resolvedMarkerData, uint32_t *markerSize); - - // Shader debug information lookup callback. - static void ShaderDebugInfoLookupCallback(const GFSDK_Aftermath_ShaderDebugInfoIdentifier *pIdentifier, PFN_GFSDK_Aftermath_SetData setShaderDebugInfo, void *pUserData); - - // Shader lookup callback. - static void ShaderLookupCallback(const GFSDK_Aftermath_ShaderBinaryHash *pShaderHash, PFN_GFSDK_Aftermath_SetData setShaderBinary, void *pUserData); - - // Shader source debug info lookup callback. - static void ShaderSourceDebugInfoLookupCallback(const GFSDK_Aftermath_ShaderDebugName *pShaderDebugName, PFN_GFSDK_Aftermath_SetData setShaderBinary, void *pUserData); - - //********************************************************* - // GPU crash tracker state. - // - - // Is the GPU crash dump tracker initialized? - bool m_initialized; - - // For thread-safe access of GPU crash tracker state. - mutable std::mutex m_mutex; - - // List of Shader Debug Information by ShaderDebugInfoIdentifier. - std::map> m_shaderDebugInfo; - - // The mock shader database. -#ifdef NSIGHT_ENABLE_SHADER_DATABASE - ShaderDatabase m_shaderDatabase; -#endif - - // App-managed marker tracking - const MarkerMap &m_markerMap; -}; -#endif diff --git a/core/client/src/c_engine.cpp b/core/client/src/c_engine.cpp index 71f3c29a3..dd90cfa19 100644 --- a/core/client/src/c_engine.cpp +++ b/core/client/src/c_engine.cpp @@ -91,9 +91,6 @@ void DLLCLIENT RunCEngine(int argc, char *argv[]) en = nullptr; } } -#ifdef PRAGMA_ENABLE_NSIGHT_AFTERMATH -void enable_nsight_aftermath_crash_tracker(); -#endif DLLCLIENT CEngine *c_engine = NULL; extern DLLCLIENT ClientState *client; @@ -124,9 +121,6 @@ CEngine::CEngine(int argc, char *argv[]) m_farZ(pragma::BaseEnvCameraComponent::DEFAULT_FAR_Z), m_fps(0), m_tFPSTime(0.f), m_tLastFrame(util::Clock::now()), m_tDeltaFrameTime(0), m_audioAPI {"fmod"} { c_engine = this; -#ifdef PRAGMA_ENABLE_NSIGHT_AFTERMATH - enable_nsight_aftermath_crash_tracker(); -#endif RegisterCallback, bool>("OnJoystickStateChanged"); RegisterCallback>>("DrawFrame"); RegisterCallback("PreDrawGUI"); diff --git a/core/client/src/debug/nsight_aftermath.cpp b/core/client/src/debug/nsight_aftermath.cpp deleted file mode 100644 index 1075fcebd..000000000 --- a/core/client/src/debug/nsight_aftermath.cpp +++ /dev/null @@ -1,327 +0,0 @@ -//********************************************************* -// -// Copyright (c) 2019-2022, NVIDIA CORPORATION. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -//********************************************************* - -#include "stdafx_client.h" -#include "pragma/debug/nsight_aftermath.hpp" - -#ifdef PRAGMA_ENABLE_NSIGHT_AFTERMATH -#include -#include -#include -#include -#pragma optimize("", off) -//********************************************************* -// GpuCrashTracker implementation -//********************************************************* - -#pragma comment(lib, "E:/projects/NVIDIA_Nsight_Aftermath_SDK_2023.1.0.23076/lib/x64/GFSDK_Aftermath_Lib.x64.lib") -GpuCrashTracker::GpuCrashTracker(const MarkerMap &markerMap) - : m_initialized(false), m_mutex(), m_shaderDebugInfo(), m_markerMap(markerMap) -#ifdef NSIGHT_ENABLE_SHADER_DATABASE - , - m_shaderDatabase() -#endif -{ -} - -GpuCrashTracker::~GpuCrashTracker() -{ - // If initialized, disable GPU crash dumps - if(m_initialized) { - GFSDK_Aftermath_DisableGpuCrashDumps(); - } -} - -// Initialize the GPU Crash Dump Tracker -void GpuCrashTracker::Initialize() -{ - // Enable GPU crash dumps and set up the callbacks for crash dump notifications, - // shader debug information notifications, and providing additional crash - // dump description data.Only the crash dump callback is mandatory. The other two - // callbacks are optional and can be omitted, by passing nullptr, if the corresponding - // functionality is not used. - // The DeferDebugInfoCallbacks flag enables caching of shader debug information data - // in memory. If the flag is set, ShaderDebugInfoCallback will be called only - // in the event of a crash, right before GpuCrashDumpCallback. If the flag is not set, - // ShaderDebugInfoCallback will be called for every shader that is compiled. - AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_EnableGpuCrashDumps(GFSDK_Aftermath_Version_API, GFSDK_Aftermath_GpuCrashDumpWatchedApiFlags_Vulkan, - GFSDK_Aftermath_GpuCrashDumpFeatureFlags_DeferDebugInfoCallbacks, // Let the Nsight Aftermath library cache shader debug information. - GpuCrashDumpCallback, // Register callback for GPU crash dumps. - ShaderDebugInfoCallback, // Register callback for shader debug information. - CrashDumpDescriptionCallback, // Register callback for GPU crash dump description. - ResolveMarkerCallback, // Register callback for resolving application-managed markers. - this)); // Set the GpuCrashTracker object as user data for the above callbacks. - - m_initialized = true; -} - -// Handler for GPU crash dump callbacks from Nsight Aftermath -void GpuCrashTracker::OnCrashDump(const void *pGpuCrashDump, const uint32_t gpuCrashDumpSize) -{ - // Make sure only one thread at a time... - std::lock_guard lock(m_mutex); - - // Write to file for later in-depth analysis with Nsight Graphics. - WriteGpuCrashDumpToFile(pGpuCrashDump, gpuCrashDumpSize); -} - -// Handler for shader debug information callbacks -void GpuCrashTracker::OnShaderDebugInfo(const void *pShaderDebugInfo, const uint32_t shaderDebugInfoSize) -{ - // Make sure only one thread at a time... - std::lock_guard lock(m_mutex); - - // Get shader debug information identifier - GFSDK_Aftermath_ShaderDebugInfoIdentifier identifier = {}; - AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GetShaderDebugInfoIdentifier(GFSDK_Aftermath_Version_API, pShaderDebugInfo, shaderDebugInfoSize, &identifier)); - - // Store information for decoding of GPU crash dumps with shader address mapping - // from within the application. - std::vector data((uint8_t *)pShaderDebugInfo, (uint8_t *)pShaderDebugInfo + shaderDebugInfoSize); - m_shaderDebugInfo[identifier].swap(data); - - // Write to file for later in-depth analysis of crash dumps with Nsight Graphics - WriteShaderDebugInformationToFile(identifier, pShaderDebugInfo, shaderDebugInfoSize); -} - -// Handler for GPU crash dump description callbacks -void GpuCrashTracker::OnDescription(PFN_GFSDK_Aftermath_AddGpuCrashDumpDescription addDescription) -{ - // Add some basic description about the crash. This is called after the GPU crash happens, but before - // the actual GPU crash dump callback. The provided data is included in the crash dump and can be - // retrieved using GFSDK_Aftermath_GpuCrashDump_GetDescription(). - addDescription(GFSDK_Aftermath_GpuCrashDumpDescriptionKey_ApplicationName, "VkHelloNsightAftermath"); - addDescription(GFSDK_Aftermath_GpuCrashDumpDescriptionKey_ApplicationVersion, "v1.0"); - addDescription(GFSDK_Aftermath_GpuCrashDumpDescriptionKey_UserDefined, "This is a GPU crash dump example."); - addDescription(GFSDK_Aftermath_GpuCrashDumpDescriptionKey_UserDefined + 1, "Engine State: Rendering."); - addDescription(GFSDK_Aftermath_GpuCrashDumpDescriptionKey_UserDefined + 2, "More user-defined information..."); -} - -// Handler for app-managed marker resolve callback -void GpuCrashTracker::OnResolveMarker(const void *pMarker, void **resolvedMarkerData, uint32_t *markerSize) -{ - // Important: the pointer passed back via resolvedMarkerData must remain valid after this function returns - // using references for all of the m_markerMap accesses ensures that the pointers refer to the persistent data - for(auto &map : m_markerMap) { - const auto &foundMarker = map.find((uint64_t)pMarker); - if(foundMarker != map.end()) { - const std::string &markerData = foundMarker->second; - // std::string::data() will return a valid pointer until the string is next modified - // we don't modify the string after calling data() here, so the pointer should remain valid - *resolvedMarkerData = (void *)markerData.data(); - *markerSize = (uint32_t)markerData.length(); - return; - } - } -} - -// Helper for writing a GPU crash dump to a file -void GpuCrashTracker::WriteGpuCrashDumpToFile(const void *pGpuCrashDump, const uint32_t gpuCrashDumpSize) -{ - // Create a GPU crash dump decoder object for the GPU crash dump. - GFSDK_Aftermath_GpuCrashDump_Decoder decoder = {}; - AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_CreateDecoder(GFSDK_Aftermath_Version_API, pGpuCrashDump, gpuCrashDumpSize, &decoder)); - - // Use the decoder object to read basic information, like application - // name, PID, etc. from the GPU crash dump. - GFSDK_Aftermath_GpuCrashDump_BaseInfo baseInfo = {}; - AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_GetBaseInfo(decoder, &baseInfo)); - - // Use the decoder object to query the application name that was set - // in the GPU crash dump description. - uint32_t applicationNameLength = 0; - AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_GetDescriptionSize(decoder, GFSDK_Aftermath_GpuCrashDumpDescriptionKey_ApplicationName, &applicationNameLength)); - - std::vector applicationName(applicationNameLength, '\0'); - - AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_GetDescription(decoder, GFSDK_Aftermath_GpuCrashDumpDescriptionKey_ApplicationName, uint32_t(applicationName.size()), applicationName.data())); - - // Create a unique file name for writing the crash dump data to a file. - // Note: due to an Nsight Aftermath bug (will be fixed in an upcoming - // driver release) we may see redundant crash dumps. As a workaround, - // attach a unique count to each generated file name. - static int count = 0; - const std::string baseFileName = std::string(applicationName.data()) + "-" + std::to_string(baseInfo.pid) + "-" + std::to_string(++count); - - // Write the crash dump data to a file using the .nv-gpudmp extension - // registered with Nsight Graphics. - filemanager::create_directory("crashdumps"); - auto path = util::Path::CreatePath(util::get_program_path()) + "crashdumps/"; - const std::string crashDumpFileName = baseFileName + ".nv-gpudmp"; - auto fullPath = path.GetString() + crashDumpFileName; - std::ofstream dumpFile(fullPath, std::ios::out | std::ios::binary); - if(dumpFile) { - dumpFile.write((const char *)pGpuCrashDump, gpuCrashDumpSize); - dumpFile.close(); - } - - // Decode the crash dump to a JSON string. - // Step 1: Generate the JSON and get the size. - uint32_t jsonSize = 0; - AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_GenerateJSON(decoder, GFSDK_Aftermath_GpuCrashDumpDecoderFlags_ALL_INFO, GFSDK_Aftermath_GpuCrashDumpFormatterFlags_NONE, ShaderDebugInfoLookupCallback, ShaderLookupCallback, ShaderSourceDebugInfoLookupCallback, this, &jsonSize)); - // Step 2: Allocate a buffer and fetch the generated JSON. - std::vector json(jsonSize); - AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_GetJSON(decoder, uint32_t(json.size()), json.data())); - - // Write the crash dump data as JSON to a file. - const std::string jsonFileName = fullPath + ".json"; - std::ofstream jsonFile(jsonFileName, std::ios::out | std::ios::binary); - if(jsonFile) { - // Write the JSON to the file (excluding string termination) - jsonFile.write(json.data(), json.size() - 1); - jsonFile.close(); - } - - // Destroy the GPU crash dump decoder object. - AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_DestroyDecoder(decoder)); -} - -// Helper for writing shader debug information to a file -void GpuCrashTracker::WriteShaderDebugInformationToFile(GFSDK_Aftermath_ShaderDebugInfoIdentifier identifier, const void *pShaderDebugInfo, const uint32_t shaderDebugInfoSize) -{ - // Create a unique file name. - const std::string filePath = "shader-" + std::to_string(identifier) + ".nvdbg"; - - std::ofstream f(filePath, std::ios::out | std::ios::binary); - if(f) { - f.write((const char *)pShaderDebugInfo, shaderDebugInfoSize); - } -} - -// Handler for shader debug information lookup callbacks. -// This is used by the JSON decoder for mapping shader instruction -// addresses to SPIR-V IL lines or GLSL source lines. -void GpuCrashTracker::OnShaderDebugInfoLookup(const GFSDK_Aftermath_ShaderDebugInfoIdentifier &identifier, PFN_GFSDK_Aftermath_SetData setShaderDebugInfo) const -{ - // Search the list of shader debug information blobs received earlier. - auto i_debugInfo = m_shaderDebugInfo.find(identifier); - if(i_debugInfo == m_shaderDebugInfo.end()) { - // Early exit, nothing found. No need to call setShaderDebugInfo. - return; - } - - // Let the GPU crash dump decoder know about the shader debug information - // that was found. - setShaderDebugInfo(i_debugInfo->second.data(), uint32_t(i_debugInfo->second.size())); -} - -// Handler for shader lookup callbacks. -// This is used by the JSON decoder for mapping shader instruction -// addresses to SPIR-V IL lines or GLSL source lines. -// NOTE: If the application loads stripped shader binaries (ie; --strip-all in spirv-remap), -// Aftermath will require access to both the stripped and the not stripped -// shader binaries. -void GpuCrashTracker::OnShaderLookup(const GFSDK_Aftermath_ShaderBinaryHash &shaderHash, PFN_GFSDK_Aftermath_SetData setShaderBinary) const -{ -#ifdef NSIGHT_ENABLE_SHADER_DATABASE - // Find shader binary data for the shader hash in the shader database. - std::vector shaderBinary; - if(!m_shaderDatabase.FindShaderBinary(shaderHash, shaderBinary)) { - // Early exit, nothing found. No need to call setShaderBinary. - return; - } - - // Let the GPU crash dump decoder know about the shader data - // that was found. - setShaderBinary(shaderBinary.data(), uint32_t(shaderBinary.size())); -#endif -} - -// Handler for shader source debug info lookup callbacks. -// This is used by the JSON decoder for mapping shader instruction addresses to -// GLSL source lines, if the shaders used by the application were compiled with -// separate debug info data files. -void GpuCrashTracker::OnShaderSourceDebugInfoLookup(const GFSDK_Aftermath_ShaderDebugName &shaderDebugName, PFN_GFSDK_Aftermath_SetData setShaderBinary) const -{ -#ifdef NSIGHT_ENABLE_SHADER_DATABASE - // Find source debug info for the shader DebugName in the shader database. - std::vector shaderBinary; - if(!m_shaderDatabase.FindShaderBinaryWithDebugData(shaderDebugName, shaderBinary)) { - // Early exit, nothing found. No need to call setShaderBinary. - return; - } - - // Let the GPU crash dump decoder know about the shader debug data that was - // found. - setShaderBinary(shaderBinary.data(), uint32_t(shaderBinary.size())); -#endif -} - -// Static callback wrapper for OnCrashDump -void GpuCrashTracker::GpuCrashDumpCallback(const void *pGpuCrashDump, const uint32_t gpuCrashDumpSize, void *pUserData) -{ - GpuCrashTracker *pGpuCrashTracker = reinterpret_cast(pUserData); - pGpuCrashTracker->OnCrashDump(pGpuCrashDump, gpuCrashDumpSize); -} - -// Static callback wrapper for OnShaderDebugInfo -void GpuCrashTracker::ShaderDebugInfoCallback(const void *pShaderDebugInfo, const uint32_t shaderDebugInfoSize, void *pUserData) -{ - GpuCrashTracker *pGpuCrashTracker = reinterpret_cast(pUserData); - pGpuCrashTracker->OnShaderDebugInfo(pShaderDebugInfo, shaderDebugInfoSize); -} - -// Static callback wrapper for OnDescription -void GpuCrashTracker::CrashDumpDescriptionCallback(PFN_GFSDK_Aftermath_AddGpuCrashDumpDescription addDescription, void *pUserData) -{ - GpuCrashTracker *pGpuCrashTracker = reinterpret_cast(pUserData); - pGpuCrashTracker->OnDescription(addDescription); -} - -// Static callback wrapper for OnResolveMarker -void GpuCrashTracker::ResolveMarkerCallback(const void *pMarker, void *pUserData, void **resolvedMarkerData, uint32_t *markerSize) -{ - GpuCrashTracker *pGpuCrashTracker = reinterpret_cast(pUserData); - pGpuCrashTracker->OnResolveMarker(pMarker, resolvedMarkerData, markerSize); -} - -// Static callback wrapper for OnShaderDebugInfoLookup -void GpuCrashTracker::ShaderDebugInfoLookupCallback(const GFSDK_Aftermath_ShaderDebugInfoIdentifier *pIdentifier, PFN_GFSDK_Aftermath_SetData setShaderDebugInfo, void *pUserData) -{ - GpuCrashTracker *pGpuCrashTracker = reinterpret_cast(pUserData); - pGpuCrashTracker->OnShaderDebugInfoLookup(*pIdentifier, setShaderDebugInfo); -} - -// Static callback wrapper for OnShaderLookup -void GpuCrashTracker::ShaderLookupCallback(const GFSDK_Aftermath_ShaderBinaryHash *pShaderHash, PFN_GFSDK_Aftermath_SetData setShaderBinary, void *pUserData) -{ - GpuCrashTracker *pGpuCrashTracker = reinterpret_cast(pUserData); - pGpuCrashTracker->OnShaderLookup(*pShaderHash, setShaderBinary); -} - -// Static callback wrapper for OnShaderSourceDebugInfoLookup -void GpuCrashTracker::ShaderSourceDebugInfoLookupCallback(const GFSDK_Aftermath_ShaderDebugName *pShaderDebugName, PFN_GFSDK_Aftermath_SetData setShaderBinary, void *pUserData) -{ - GpuCrashTracker *pGpuCrashTracker = reinterpret_cast(pUserData); - pGpuCrashTracker->OnShaderSourceDebugInfoLookup(*pShaderDebugName, setShaderBinary); -} - -void enable_nsight_aftermath_crash_tracker() -{ - static GpuCrashTracker::MarkerMap markerMap; - static GpuCrashTracker tracker {markerMap}; - tracker.Initialize(); -} - -#endif diff --git a/core/client/src/rendering/c_render_context.cpp b/core/client/src/rendering/c_render_context.cpp index 914d9615d..001c3f273 100644 --- a/core/client/src/rendering/c_render_context.cpp +++ b/core/client/src/rendering/c_render_context.cpp @@ -8,6 +8,7 @@ #include "stdafx_cengine.h" #include "pragma/rendering/c_render_context.hpp" #include "pragma/rendering/render_apis.hpp" +#include "pragma/debug/debug_utils.hpp" #include #include #include @@ -28,7 +29,15 @@ static spdlog::logger &LOGGER = pragma::register_logger("prosper"); static spdlog::logger &LOGGER_VALIDATION = pragma::register_logger("prosper_validation"); RenderContext::RenderContext() : m_monitor(nullptr), m_renderAPI {"vulkan"} {} -RenderContext::~RenderContext() { m_graphicsAPILib = nullptr; } +RenderContext::~RenderContext() +{ + if(m_graphicsAPILib) { + auto *detach = m_graphicsAPILib->FindSymbolAddress("pragma_detach"); + if(detach) + detach(); + } + m_graphicsAPILib = nullptr; +} DLLNETWORK std::optional g_customTitle; extern bool g_cpuRendering; void RenderContext::InitializeRenderAPI() @@ -99,6 +108,7 @@ void RenderContext::InitializeRenderAPI() } m_renderContext->SetLogHandler(&pragma::log, &pragma::is_log_level_enabled); + m_renderContext->SetProfilingHandler([](const char *taskName) { pragma::debug::start_profiling_task(taskName); }, []() { pragma::debug::end_profiling_task(); }); prosper::Callbacks callbacks {}; callbacks.validationCallback = [this](prosper::DebugMessageSeverityFlags severityFlags, const std::string &message) { ValidationCallback(severityFlags, message); };