From 73eb5f633d7eab38eb9b22ece6b5c6aeb0bb9f19 Mon Sep 17 00:00:00 2001 From: Dmytro Bulatov Date: Mon, 17 Feb 2025 04:14:36 +0900 Subject: [PATCH 1/6] Refactored output, added out to file option --- CMakeLists.txt | 36 +- README.md | 7 +- Src/AgsData.cpp | 86 +- Src/AmdDeviceInfoData.cpp | 37 +- Src/IntelData.cpp | 46 +- Src/Json.cpp | 225 ---- Src/Json.hpp | 41 - Src/Main.cpp | 1120 +++++++---------- Src/NvApiData.cpp | 247 ++-- Src/Printer.cpp | 104 ++ Src/Printer.hpp | 43 + Src/Printing.cpp | 380 ------ Src/Printing.hpp | 44 - .../ConsoleReportFormatter.cpp | 416 ++++++ .../ConsoleReportFormatter.hpp | 73 ++ Src/ReportFormatter/JSONReportFormatter.cpp | 234 ++++ Src/ReportFormatter/JSONReportFormatter.hpp | 69 + Src/ReportFormatter/ReportFormatter.cpp | 230 ++++ Src/ReportFormatter/ReportFormatter.hpp | 141 +++ Src/VulkanData.cpp | 33 +- Src/pch.hpp | 1 + 21 files changed, 2013 insertions(+), 1600 deletions(-) delete mode 100644 Src/Json.cpp delete mode 100644 Src/Json.hpp create mode 100644 Src/Printer.cpp create mode 100644 Src/Printer.hpp delete mode 100644 Src/Printing.cpp delete mode 100644 Src/Printing.hpp create mode 100644 Src/ReportFormatter/ConsoleReportFormatter.cpp create mode 100644 Src/ReportFormatter/ConsoleReportFormatter.hpp create mode 100644 Src/ReportFormatter/JSONReportFormatter.cpp create mode 100644 Src/ReportFormatter/JSONReportFormatter.hpp create mode 100644 Src/ReportFormatter/ReportFormatter.cpp create mode 100644 Src/ReportFormatter/ReportFormatter.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 626ed0b..ee4b389 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,39 @@ cmake_minimum_required(VERSION 3.17) project(D3d12info LANGUAGES CXX) set(CMAKE_CXX_STANDARD 20) -file(GLOB CPP_FILES "Src/*.cpp") -file(GLOB HPP_FILES "Src/*.hpp") +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +set(CPP_FILES + Src/AgsData.cpp + Src/AmdDeviceInfoData.cpp + Src/IntelData.cpp + Src/Main.cpp + Src/NvApiData.cpp + Src/Printer.cpp + Src/Resources.rc + Src/Utils.cpp + Src/VulkanData.cpp + Src/ReportFormatter/ConsoleReportFormatter.cpp + Src/ReportFormatter/JSONReportFormatter.cpp + Src/ReportFormatter/ReportFormatter.cpp +) + +set(HPP_FILES + Src/AgsData.hpp + Src/AmdDeviceInfoData.hpp + Src/Enums.hpp + Src/IntelData.hpp + Src/NvApiData.hpp + Src/pch.hpp + Src/Printer.hpp + Src/Utils.hpp + Src/VulkanData.hpp + Src/ReportFormatter/ConsoleReportFormatter.hpp + Src/ReportFormatter/JSONReportFormatter.hpp + Src/ReportFormatter/ReportFormatter.hpp +) + set(RAPIDJSON_NATVIS_FILE "Src/ThirdParty/rapidjson/contrib/natvis/rapidjson.natvis") set(INTEL_GPUDETECT_CFG_FILE "Src/ThirdParty/gpudetect/IntelGfx.cfg") @@ -82,6 +113,7 @@ function(add_my_executable USE_PREVIEW_AGILITY_SDK) endif() add_executable(${EXE_NAME} ${CPP_FILES} ${HPP_FILES}) + target_include_directories(${EXE_NAME} PRIVATE Src) # Change Visual C++ runtime library to get rid of dependency on Visual C++ Redistributable set_property(TARGET ${EXE_NAME} PROPERTY diff --git a/README.md b/README.md index 3ea0055..6c1254a 100644 --- a/README.md +++ b/README.md @@ -60,9 +60,12 @@ Options: -h --Help Only print this help (command line syntax). -l --List Only print the list of all adapters. -a --Adapter= Print details of adapter at specified index. - --AllNonSoftware Print details of all (except WARP and Software) adapters (default behavior). - --AllAdapters Print details of all (except WARP) adapters. + --AllNonSoftware Print details of all (except Software) adapters (default behavior). + --AllAdapters Print details of all adapters. -j --JSON Print output in JSON format instead of human-friendly text. + --JSONPrettyPrint Print JSON in human friendly form. (default behavior) + --JSONNoPrettyPrint Print JSON in minimal size form. + -o --OutputToFile= Output to specified file. -f --Formats Include information about DXGI format capabilities. --MetaCommands Include information about meta commands. -e --Enums Include information about all known enums and their values. diff --git a/Src/AgsData.cpp b/Src/AgsData.cpp index 39234e7..8f390d1 100644 --- a/Src/AgsData.cpp +++ b/Src/AgsData.cpp @@ -8,10 +8,9 @@ License: MIT For more information, see files README.md, LICENSE.txt. */ #include "AgsData.hpp" -#include "Printing.hpp" #include "Utils.hpp" -#include "Json.hpp" #include "Enums.hpp" +#include "ReportFormatter/ReportFormatter.hpp" // Macro set by Cmake. #if USE_AGS @@ -67,22 +66,11 @@ static bool FindDevice(const AGS_Initialize_RAII::DeviceId& id, int& outIndex) void AGS_Initialize_RAII::PrintStaticParams() { - Print_string(L"AMD_AGS_VERSION", std::format(L"{}.{}.{}", + ReportFormatter::GetInstance().AddFieldString(L"AMD_AGS_VERSION", std::format(L"{}.{}.{}", AMD_AGS_VERSION_MAJOR, AMD_AGS_VERSION_MINOR, AMD_AGS_VERSION_PATCH).c_str()); const uint32_t version = (uint32_t)agsGetVersionNumber(); - if(g_UseJson) - { - Print_hex32(L"agsGetVersionNumber", version); - } - else - { - wstring s = std::format(L"{}.{}.{}", - version >> 22, - (version >> 12) & 0b11'1111'1111, - version & 0b1111'1111'1111); - Print_string(L"agsGetVersionNumber", s.c_str()); - } + ReportFormatter::GetInstance().AddFieldAMDVersion(L"agsGetVersionNumber", version); } AGS_Initialize_RAII::AGS_Initialize_RAII() @@ -110,9 +98,9 @@ void AGS_Initialize_RAII::PrintData() if(IsStrEmpty(g_GpuInfo.driverVersion) && IsStrEmpty(g_GpuInfo.radeonSoftwareVersion)) return; - ScopedStructRegion region(L"AGSGPUInfo"); - Print_string(L"driverVersion", StrToWstr(g_GpuInfo.driverVersion, CP_ACP).c_str()); - Print_string(L"radeonSoftwareVersion", StrToWstr(g_GpuInfo.radeonSoftwareVersion, CP_ACP).c_str()); + ReportScopeObject region(L"AGSGPUInfo"); + ReportFormatter::GetInstance().AddFieldString(L"driverVersion", StrToWstr(g_GpuInfo.driverVersion, CP_ACP).c_str()); + ReportFormatter::GetInstance().AddFieldString(L"radeonSoftwareVersion", StrToWstr(g_GpuInfo.radeonSoftwareVersion, CP_ACP).c_str()); } void AGS_Initialize_RAII::PrintAgsDeviceData(const DeviceId& id) @@ -124,23 +112,23 @@ void AGS_Initialize_RAII::PrintAgsDeviceData(const DeviceId& id) return; const AGSDeviceInfo& device = g_GpuInfo.devices[deviceIndex]; - ScopedStructRegion region(L"AGSDeviceInfo"); - Print_string(L"adapterString", StrToWstr(device.adapterString, CP_ACP).c_str()); - PrintEnum(L"asicFamily", device.asicFamily, Enum_AGSDeviceInfo_AsicFamily); - Print_BOOL(L"isAPU", device.isAPU); - Print_BOOL(L"isExternal", device.isExternal); - PrintVendorId(L"vendorId", (uint32_t)device.vendorId); - Print_hex32(L"deviceId", (uint32_t)device.deviceId); - Print_hex32(L"revisionId", (uint32_t)device.revisionId); - Print_int32(L"numCUs", device.numCUs); - Print_int32(L"numWGPs", device.numWGPs); - Print_int32(L"numROPs", device.numROPs); - Print_int32(L"coreClock", device.coreClock, L"MHz"); - Print_int32(L"memoryClock", device.memoryClock, L"MHz"); - Print_int32(L"memoryBandwidth", device.memoryBandwidth, L"MB/s"); - Print_float(L"teraFlops", device.teraFlops, L"TFLOPS"); - Print_size(L"localMemoryInBytes", device.localMemoryInBytes); - Print_size(L"sharedMemoryInBytes", device.sharedMemoryInBytes); + ReportScopeObject region(L"AGSDeviceInfo"); + ReportFormatter::GetInstance().AddFieldString(L"adapterString", StrToWstr(device.adapterString, CP_ACP).c_str()); + ReportFormatter::GetInstance().AddFieldEnum(L"asicFamily", device.asicFamily, Enum_AGSDeviceInfo_AsicFamily); + ReportFormatter::GetInstance().AddFieldBool(L"isAPU", device.isAPU); + ReportFormatter::GetInstance().AddFieldBool(L"isExternal", device.isExternal); + ReportFormatter::GetInstance().AddFieldVendorId(L"vendorId", (uint32_t)device.vendorId); + ReportFormatter::GetInstance().AddFieldHex32(L"deviceId", (uint32_t)device.deviceId); + ReportFormatter::GetInstance().AddFieldHex32(L"revisionId", (uint32_t)device.revisionId); + ReportFormatter::GetInstance().AddFieldInt32(L"numCUs", device.numCUs); + ReportFormatter::GetInstance().AddFieldInt32(L"numWGPs", device.numWGPs); + ReportFormatter::GetInstance().AddFieldInt32(L"numROPs", device.numROPs); + ReportFormatter::GetInstance().AddFieldInt32(L"coreClock", device.coreClock, L"MHz"); + ReportFormatter::GetInstance().AddFieldInt32(L"memoryClock", device.memoryClock, L"MHz"); + ReportFormatter::GetInstance().AddFieldInt32(L"memoryBandwidth", device.memoryBandwidth, L"MB/s"); + ReportFormatter::GetInstance().AddFieldFloat(L"teraFlops", device.teraFlops, L"TFLOPS"); + ReportFormatter::GetInstance().AddFieldSize(L"localMemoryInBytes", device.localMemoryInBytes); + ReportFormatter::GetInstance().AddFieldSize(L"sharedMemoryInBytes", device.sharedMemoryInBytes); } ComPtr AGS_Initialize_RAII::CreateDeviceAndPrintData(IDXGIAdapter* adapter, D3D_FEATURE_LEVEL featureLevel) @@ -163,20 +151,20 @@ ComPtr AGS_Initialize_RAII::CreateDeviceAndPrintData(IDXGIAdapter* ComPtr device{returnedParams.pDevice}; g_DeviceCreatedWithAgs = true; - ScopedStructRegion region(L"AGSDX12ReturnedParams::ExtensionsSupported"); - Print_BOOL(L"intrinsics16", returnedParams.extensionsSupported.intrinsics16); - Print_BOOL(L"intrinsics17", returnedParams.extensionsSupported.intrinsics17); - Print_BOOL(L"userMarkers", returnedParams.extensionsSupported.userMarkers); - Print_BOOL(L"appRegistration", returnedParams.extensionsSupported.appRegistration); - Print_BOOL(L"UAVBindSlot", returnedParams.extensionsSupported.UAVBindSlot); - Print_BOOL(L"intrinsics19", returnedParams.extensionsSupported.intrinsics19); - Print_BOOL(L"baseVertex", returnedParams.extensionsSupported.baseVertex); - Print_BOOL(L"baseInstance", returnedParams.extensionsSupported.baseInstance); - Print_BOOL(L"getWaveSize", returnedParams.extensionsSupported.getWaveSize); - Print_BOOL(L"floatConversion", returnedParams.extensionsSupported.floatConversion); - Print_BOOL(L"readLaneAt", returnedParams.extensionsSupported.readLaneAt); - Print_BOOL(L"rayHitToken", returnedParams.extensionsSupported.rayHitToken); - Print_BOOL(L"shaderClock", returnedParams.extensionsSupported.shaderClock); + ReportScopeObject region(L"AGSDX12ReturnedParams::ExtensionsSupported"); + ReportFormatter::GetInstance().AddFieldBool(L"intrinsics16", returnedParams.extensionsSupported.intrinsics16); + ReportFormatter::GetInstance().AddFieldBool(L"intrinsics17", returnedParams.extensionsSupported.intrinsics17); + ReportFormatter::GetInstance().AddFieldBool(L"userMarkers", returnedParams.extensionsSupported.userMarkers); + ReportFormatter::GetInstance().AddFieldBool(L"appRegistration", returnedParams.extensionsSupported.appRegistration); + ReportFormatter::GetInstance().AddFieldBool(L"UAVBindSlot", returnedParams.extensionsSupported.UAVBindSlot); + ReportFormatter::GetInstance().AddFieldBool(L"intrinsics19", returnedParams.extensionsSupported.intrinsics19); + ReportFormatter::GetInstance().AddFieldBool(L"baseVertex", returnedParams.extensionsSupported.baseVertex); + ReportFormatter::GetInstance().AddFieldBool(L"baseInstance", returnedParams.extensionsSupported.baseInstance); + ReportFormatter::GetInstance().AddFieldBool(L"getWaveSize", returnedParams.extensionsSupported.getWaveSize); + ReportFormatter::GetInstance().AddFieldBool(L"floatConversion", returnedParams.extensionsSupported.floatConversion); + ReportFormatter::GetInstance().AddFieldBool(L"readLaneAt", returnedParams.extensionsSupported.readLaneAt); + ReportFormatter::GetInstance().AddFieldBool(L"rayHitToken", returnedParams.extensionsSupported.rayHitToken); + ReportFormatter::GetInstance().AddFieldBool(L"shaderClock", returnedParams.extensionsSupported.shaderClock); return device; } diff --git a/Src/AmdDeviceInfoData.cpp b/Src/AmdDeviceInfoData.cpp index cabbb1b..940b064 100644 --- a/Src/AmdDeviceInfoData.cpp +++ b/Src/AmdDeviceInfoData.cpp @@ -8,10 +8,9 @@ License: MIT For more information, see files README.md, LICENSE.txt. */ #include "AmdDeviceInfoData.hpp" -#include "Printing.hpp" #include "Utils.hpp" -#include "Json.hpp" #include "Enums.hpp" +#include "ReportFormatter/ReportFormatter.hpp" // Macro set by Cmake. #if USE_AMD_DEVICE_INFO @@ -116,7 +115,7 @@ static const GDT_GfxCardInfo* FindCardInfo(const AmdDeviceInfo_Initialize_RAII:: void AmdDeviceInfo_Initialize_RAII::PrintStaticParams() { - Print_string(L"AMD device_info compiled version", AMD_DEVICE_INFO_COMPILED_VERSION); + ReportFormatter::GetInstance().AddFieldString(L"AMD device_info compiled version", AMD_DEVICE_INFO_COMPILED_VERSION); } void AmdDeviceInfo_Initialize_RAII::PrintDeviceData(const DeviceId& id) @@ -126,12 +125,12 @@ void AmdDeviceInfo_Initialize_RAII::PrintDeviceData(const DeviceId& id) return; { - ScopedStructRegion region{L"AMD GDT_GfxCardInfo"}; - PrintEnum(L"asicType", cardInfo->m_asicType, Enum_GDT_HW_ASIC_TYPE); - PrintEnum(L"generation", cardInfo->m_generation, Enum_GDT_HW_GENERATION); - Print_BOOL(L"APU", cardInfo->m_bAPU ? TRUE : FALSE); - Print_string(L"CALName", StrToWstr(cardInfo->m_szCALName, CP_UTF8).c_str()); - Print_string(L"MarketingName", StrToWstr(cardInfo->m_szMarketingName, CP_UTF8).c_str()); + ReportScopeObject region{L"AMD GDT_GfxCardInfo"}; + ReportFormatter::GetInstance().AddFieldEnum(L"asicType", cardInfo->m_asicType, Enum_GDT_HW_ASIC_TYPE); + ReportFormatter::GetInstance().AddFieldEnum(L"generation", cardInfo->m_generation, Enum_GDT_HW_GENERATION); + ReportFormatter::GetInstance().AddFieldBool(L"APU", cardInfo->m_bAPU ? TRUE : FALSE); + ReportFormatter::GetInstance().AddFieldString(L"CALName", StrToWstr(cardInfo->m_szCALName, CP_UTF8).c_str()); + ReportFormatter::GetInstance().AddFieldString(L"MarketingName", StrToWstr(cardInfo->m_szMarketingName, CP_UTF8).c_str()); } if(cardInfo->m_asicType >= 0 && cardInfo->m_asicType < gs_deviceInfoSize) @@ -139,16 +138,16 @@ void AmdDeviceInfo_Initialize_RAII::PrintDeviceData(const DeviceId& id) const GDT_DeviceInfo& devInfo = gs_deviceInfo[cardInfo->m_asicType]; if(devInfo.m_deviceInfoValid) { - ScopedStructRegion region(L"AMD GDT_DeviceInfo"); - Print_uint64(L"NumShaderEngines", devInfo.m_nNumShaderEngines); // Number of shader engines. - Print_uint64(L"MaxWavePerSIMD", devInfo.m_nMaxWavePerSIMD); // Number of wave slots per SIMD. - Print_uint64(L"ClocksPrim", devInfo.m_suClocksPrim); // Number of clocks it takes to process a primitive. - Print_uint64(L"NumSQMaxCounters", devInfo.m_nNumSQMaxCounters); // Max number of SQ counters. - Print_uint64(L"NumPrimPipes", devInfo.m_nNumPrimPipes); // Number of primitive pipes. - Print_uint64(L"WaveSize", devInfo.m_nWaveSize); // Wavefront size. - Print_uint64(L"NumSHPerSE", devInfo.m_nNumSHPerSE); // Number of shader array per Shader Engine. - Print_uint64(L"NumCUPerSH", devInfo.m_nNumCUPerSH); // Number of compute unit per Shader Array. - Print_uint64(L"NumSIMDPerCU", devInfo.m_nNumSIMDPerCU); // Number of SIMDs per Compute unit. + ReportScopeObject region(L"AMD GDT_DeviceInfo"); + ReportFormatter::GetInstance().AddFieldUint64(L"NumShaderEngines", devInfo.m_nNumShaderEngines); // Number of shader engines. + ReportFormatter::GetInstance().AddFieldUint64(L"MaxWavePerSIMD", devInfo.m_nMaxWavePerSIMD); // Number of wave slots per SIMD. + ReportFormatter::GetInstance().AddFieldUint64(L"ClocksPrim", devInfo.m_suClocksPrim); // Number of clocks it takes to process a primitive. + ReportFormatter::GetInstance().AddFieldUint64(L"NumSQMaxCounters", devInfo.m_nNumSQMaxCounters); // Max number of SQ counters. + ReportFormatter::GetInstance().AddFieldUint64(L"NumPrimPipes", devInfo.m_nNumPrimPipes); // Number of primitive pipes. + ReportFormatter::GetInstance().AddFieldUint64(L"WaveSize", devInfo.m_nWaveSize); // Wavefront size. + ReportFormatter::GetInstance().AddFieldUint64(L"NumSHPerSE", devInfo.m_nNumSHPerSE); // Number of shader array per Shader Engine. + ReportFormatter::GetInstance().AddFieldUint64(L"NumCUPerSH", devInfo.m_nNumCUPerSH); // Number of compute unit per Shader Array. + ReportFormatter::GetInstance().AddFieldUint64(L"NumSIMDPerCU", devInfo.m_nNumSIMDPerCU); // Number of SIMDs per Compute unit. } } } diff --git a/Src/IntelData.cpp b/Src/IntelData.cpp index 3b8380f..280fc88 100644 --- a/Src/IntelData.cpp +++ b/Src/IntelData.cpp @@ -13,10 +13,10 @@ License: Apache 2.0 See the original library in directory: Src\ThirdParty\gpudetect */ #include "IntelData.hpp" -#include "Printing.hpp" #include "Utils.hpp" -#include "Json.hpp" #include "Enums.hpp" +#include "ReportFormatter/ReportFormatter.hpp" +#include "Printer.hpp" // Macro set by Cmake. #if USE_INTEL_GPUDETECT @@ -1549,7 +1549,7 @@ PresetLevel GetDefaultFidelityPreset( const GPUData* const gpuData ) } else { - fprintf( stderr, "Error: %s not found! Fallback to default presets.\n", cfgFileName ); + ErrorPrinter::PrintFormat("Error: {} not found! Fallback to default presets.", std::make_format_args(cfgFileName)); } // @@ -1979,7 +1979,7 @@ namespace IntelData void PrintStaticParams() { - Print_string(L"Intel GPU Detect compiled version", INTEL_GPU_DETECT_COMPILED_VERSION); + ReportFormatter::GetInstance().AddFieldString(L"Intel GPU Detect compiled version", INTEL_GPU_DETECT_COMPILED_VERSION); } void PrintAdapterData(IDXGIAdapter* adapter) @@ -1994,29 +1994,29 @@ void PrintAdapterData(IDXGIAdapter* adapter) if(r != EXIT_SUCCESS) return; - ScopedStructRegion region(L"Intel GPUDetect::GPUData"); - PrintVendorId(L"VendorId", gpuData.vendorID); - Print_hex32(L"deviceID", gpuData.deviceID); - Print_BOOL(L"isUMAArchitecture", gpuData.isUMAArchitecture ? TRUE : FALSE); - Print_size(L"videoMemory", gpuData.videoMemory); - Print_string(L"description", gpuData.description); - Print_hex32(L"extensionVersion", gpuData.extensionVersion); - Print_BOOL(L"intelExtensionAvailability", gpuData.intelExtensionAvailability ? TRUE : FALSE); + ReportScopeObject region(L"Intel GPUDetect::GPUData"); + ReportFormatter::GetInstance().AddFieldVendorId(L"VendorId", gpuData.vendorID); + ReportFormatter::GetInstance().AddFieldHex32(L"deviceID", gpuData.deviceID); + ReportFormatter::GetInstance().AddFieldBool(L"isUMAArchitecture", gpuData.isUMAArchitecture ? TRUE : FALSE); + ReportFormatter::GetInstance().AddFieldSize(L"videoMemory", gpuData.videoMemory); + ReportFormatter::GetInstance().AddFieldString(L"description", gpuData.description); + ReportFormatter::GetInstance().AddFieldHex32(L"extensionVersion", gpuData.extensionVersion); + ReportFormatter::GetInstance().AddFieldBool(L"intelExtensionAvailability", gpuData.intelExtensionAvailability ? TRUE : FALSE); r = GPUDetect::InitDxDriverVersion(&gpuData); if(r == EXIT_SUCCESS && gpuData.d3dRegistryDataAvailability) { char driverVersionStr[19] = {}; GPUDetect::GetDriverVersionAsCString(&gpuData, driverVersionStr, _countof(driverVersionStr)); - Print_string(L"dxDriverVersion", StrToWstr(driverVersionStr, CP_ACP).c_str()); - Print_uint32(L"driverInfo.driverReleaseRevision", gpuData.driverInfo.driverReleaseRevision); - Print_uint32(L"driverInfo.driverBuildNumber", gpuData.driverInfo.driverBuildNumber); + ReportFormatter::GetInstance().AddFieldString(L"dxDriverVersion", StrToWstr(driverVersionStr, CP_ACP).c_str()); + ReportFormatter::GetInstance().AddFieldUint32(L"driverInfo.driverReleaseRevision", gpuData.driverInfo.driverReleaseRevision); + ReportFormatter::GetInstance().AddFieldUint32(L"driverInfo.driverBuildNumber", gpuData.driverInfo.driverBuildNumber); } if(gpuData.vendorID == GPUDetect::INTEL_VENDOR_ID) { const GPUDetect::PresetLevel presetLevel = GPUDetect::GetDefaultFidelityPreset(&gpuData); - PrintEnum(L"DefaultFidelityPreset", (uint32_t)presetLevel, GPUDetect::Enum_PresetLevel); + ReportFormatter::GetInstance().AddFieldEnum(L"DefaultFidelityPreset", (uint32_t)presetLevel, GPUDetect::Enum_PresetLevel); r = GPUDetect::InitCounterInfo(&gpuData, device.Get()); if(r == EXIT_SUCCESS) @@ -2024,24 +2024,24 @@ void PrintAdapterData(IDXGIAdapter* adapter) string architectureStr = GPUDetect::GetIntelGPUArchitectureString(gpuData.architecture); if(architectureStr == "Unknown") architectureStr = std::format("Unknown ({})", (uint32_t)gpuData.architecture); - Print_string(L"GPUArchitecture", StrToWstr(architectureStr.c_str(), CP_ACP).c_str()); + ReportFormatter::GetInstance().AddFieldString(L"GPUArchitecture", StrToWstr(architectureStr.c_str(), CP_ACP).c_str()); const GPUDetect::IntelGraphicsGeneration generation = GPUDetect::GetIntelGraphicsGeneration(gpuData.architecture); string generationStr = GPUDetect::GetIntelGraphicsGenerationString(generation); if(generationStr == "Unknown") generationStr = std::format("Unknown ({})", (uint32_t)generation); - Print_string(L"GraphicsGeneration", StrToWstr(generationStr.c_str(), CP_ACP).c_str()); + ReportFormatter::GetInstance().AddFieldString(L"GraphicsGeneration", StrToWstr(generationStr.c_str(), CP_ACP).c_str()); if(gpuData.advancedCounterDataAvailability) { - Print_uint32(L"euCount", gpuData.euCount); - Print_uint32(L"packageTDP", gpuData.packageTDP, L"W"); - Print_uint32(L"maxFillRate", gpuData.maxFillRate, L"pixels/clock"); + ReportFormatter::GetInstance().AddFieldUint32(L"euCount", gpuData.euCount); + ReportFormatter::GetInstance().AddFieldUint32(L"packageTDP", gpuData.packageTDP, L"W"); + ReportFormatter::GetInstance().AddFieldUint32(L"maxFillRate", gpuData.maxFillRate, L"pixels/clock"); } - Print_uint32(L"maxFrequency", gpuData.maxFrequency, L"MHz"); - Print_uint32(L"minFrequency", gpuData.minFrequency, L"MHz"); + ReportFormatter::GetInstance().AddFieldUint32(L"maxFrequency", gpuData.maxFrequency, L"MHz"); + ReportFormatter::GetInstance().AddFieldUint32(L"minFrequency", gpuData.minFrequency, L"MHz"); } } } diff --git a/Src/Json.cpp b/Src/Json.cpp deleted file mode 100644 index 6796e34..0000000 --- a/Src/Json.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/* -This file is part of D3d12info project: -https://github.com/sawickiap/D3d12info - -Copyright (c) 2018-2024 Adam Sawicki, https://asawicki.info -License: MIT - -For more information, see files README.md, LICENSE.txt. -*/ -#include "Json.hpp" - -#define RAPIDJSON_HAS_STDSTRING 1 -#define RAPIDJSON_NO_SIZETYPEDEFINE -#define RAPIDJSON_SSE2 -namespace rapidjson { typedef size_t SizeType; } - -#include "ThirdParty/rapidjson/include/rapidjson/document.h" -#include "ThirdParty/rapidjson/include/rapidjson/prettywriter.h" -#include "ThirdParty/rapidjson/include/rapidjson/stringbuffer.h" -#include "ThirdParty/rapidjson/include/rapidjson/allocators.h" -#include "ThirdParty/rapidjson/include/rapidjson/encodings.h" -#include "ThirdParty/rapidjson/include/rapidjson/error/en.h" - -namespace Json -{ - - -//////////////////////////////////////////////////////////////////////////////// -// PRIVATE IMPLEMENTATION - -using ValueType = rapidjson::GenericValue< rapidjson::UTF16<> >; -using StringRefType = rapidjson::GenericStringRef; -static rapidjson::GenericDocument< rapidjson::UTF16<> > g_Document{rapidjson::kObjectType}; -static std::vector g_ValueStack; -static wstring g_CurrentKey; - -static void PushValue(ValueType&& val) -{ - using namespace rapidjson; - assert(!g_ValueStack.empty()); - ValueType* const currVal = g_ValueStack.back(); - const bool newValNeedsPush = val.GetType() == kObjectType || val.GetType() == kArrayType; - switch(currVal->GetType()) - { - case kArrayType: - { - currVal->PushBack(val, g_Document.GetAllocator()); - if(newValNeedsPush) - g_ValueStack.push_back(&currVal->GetArray()[currVal->GetArray().Size() - 1]); - break; - } - case kObjectType: - { - assert(!g_CurrentKey.empty()); - currVal->AddMember( - ValueType{g_CurrentKey.data(), g_CurrentKey.length(), g_Document.GetAllocator()}, - val, g_Document.GetAllocator()); - if(newValNeedsPush) - g_ValueStack.push_back(&currVal->GetObj()[g_CurrentKey]); - g_CurrentKey.clear(); - break; - } - default: - assert(0); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// PUBLIC INTERFACE - -void Begin() -{ - assert(g_ValueStack.empty() && g_CurrentKey.empty()); - g_ValueStack.push_back(&g_Document); -} - -wstring End() -{ - using namespace rapidjson; - using StringBufferType = GenericStringBuffer< UTF16LE<> >; - StringBufferType stringBuffer; - { - PrettyWriter< StringBufferType, UTF16<>, UTF16LE<> > writer{stringBuffer}; - g_Document.Accept(writer); - } - - assert(g_ValueStack.size() == 1 && g_ValueStack[0] == &g_Document && g_CurrentKey.empty()); - g_ValueStack.clear(); - - return wstring{stringBuffer.GetString(), stringBuffer.GetLength()}; -} - -void WriteString(const wchar_t* str, size_t length) -{ - using namespace rapidjson; - assert(!g_ValueStack.empty()); - ValueType* const currVal = g_ValueStack.back(); - // Writing key - if(currVal->GetType() == kObjectType && g_CurrentKey.empty()) - g_CurrentKey = wstring{str, length}; - // Writing value - else - PushValue(ValueType{str, length, g_Document.GetAllocator()}); -} - -void WriteString(const wchar_t* str) -{ - WriteString(str, wcslen(str)); -} - -void WriteString(wstring&& str) -{ - using namespace rapidjson; - assert(!g_ValueStack.empty()); - ValueType* const currVal = g_ValueStack.back(); - // Writing key - if(currVal->GetType() == kObjectType && g_CurrentKey.empty()) - g_CurrentKey = std::move(str); - // Writing value - else - PushValue(ValueType{str.data(), str.length(), g_Document.GetAllocator()}); -} - -void WriteNull() -{ - PushValue(ValueType{rapidjson::kNullType}); -} - -void WriteBool(bool value) -{ - PushValue(ValueType{value}); - -} - -void WriteNumber(uint32_t value) -{ - PushValue(ValueType{value}); -} - -void WriteNumber(uint64_t value) -{ - PushValue(ValueType{value}); -} - -void WriteNumber(int32_t value) -{ - PushValue(ValueType{value}); -} - -void WriteNumber(float value) -{ - PushValue(ValueType{value}); -} - -void BeginObject() -{ - PushValue(ValueType{rapidjson::kObjectType}); -} - -void EndObject() -{ - assert(!g_ValueStack.empty() && g_ValueStack.back()->GetType() == rapidjson::kObjectType); - g_ValueStack.pop_back(); -} - -void BeginArray() -{ - PushValue(ValueType{rapidjson::kArrayType}); -} - -void EndArray() -{ - assert(!g_ValueStack.empty() && g_ValueStack.back()->GetType() == rapidjson::kArrayType); - g_ValueStack.pop_back(); -} - -void WriteNameAndString(const wchar_t* name, const wchar_t* str, size_t length) -{ - WriteString(name); - WriteString(str, length); -} - -void WriteNameAndString(const wchar_t* name, const wchar_t* str) -{ - WriteString(name); - WriteString(str); -} - -void WriteNameAndString(const wchar_t* name, wstring&& str) -{ - WriteString(name); - WriteString(std::move(str)); -} - -void WriteNameAndBool(const wchar_t* name, bool value) -{ - WriteString(name); - WriteBool(value); -} - -void WriteNameAndNumber(const wchar_t* name, uint32_t value) -{ - WriteString(name); - WriteNumber(value); -} - -void WriteNameAndNumber(const wchar_t* name, uint64_t value) -{ - WriteString(name); - WriteNumber(value); -} - -void WriteNameAndNumber(const wchar_t* name, int32_t value) -{ - WriteString(name); - WriteNumber(value); -} - -void WriteNameAndNumber(const wchar_t* name, float value) -{ - WriteString(name); - WriteNumber(value); -} - -} // namespace Json diff --git a/Src/Json.hpp b/Src/Json.hpp deleted file mode 100644 index 81d7cdd..0000000 --- a/Src/Json.hpp +++ /dev/null @@ -1,41 +0,0 @@ -/* -This file is part of D3d12info project: -https://github.com/sawickiap/D3d12info - -Copyright (c) 2018-2024 Adam Sawicki, https://asawicki.info -License: MIT - -For more information, see files README.md, LICENSE.txt. -*/ -#pragma once - -namespace Json -{ - -void Begin(); -wstring End(); - -void WriteString(const wchar_t* str, size_t length); -void WriteString(const wchar_t* str); -void WriteString(wstring&& str); -void WriteNull(); -void WriteBool(bool value); -void WriteNumber(uint32_t value); -void WriteNumber(uint64_t value); -void WriteNumber(int32_t value); -void WriteNumber(float value); -void BeginObject(); -void EndObject(); -void BeginArray(); -void EndArray(); - -void WriteNameAndString(const wchar_t* name, const wchar_t* str, size_t length); -void WriteNameAndString(const wchar_t* name, const wchar_t* str); -void WriteNameAndString(const wchar_t* name, wstring&& str); -void WriteNameAndBool(const wchar_t* name, bool value); -void WriteNameAndNumber(const wchar_t* name, uint32_t value); -void WriteNameAndNumber(const wchar_t* name, uint64_t value); -void WriteNameAndNumber(const wchar_t* name, int32_t value); -void WriteNameAndNumber(const wchar_t* name, float value); - -} // namespace Json diff --git a/Src/Main.cpp b/Src/Main.cpp index 6c0fc3e..5e40257 100644 --- a/Src/Main.cpp +++ b/Src/Main.cpp @@ -14,8 +14,8 @@ For more information, see files README.md, LICENSE.txt. #include "VulkanData.hpp" #include "Utils.hpp" #include "Enums.hpp" -#include "Json.hpp" -#include "Printing.hpp" +#include "Printer.hpp" +#include "ReportFormatter/ReportFormatter.hpp" // For Direct3D 12 Agility SDK extern "C" @@ -79,9 +79,16 @@ PFN_D3D12_GET_INTERFACE g_D3D12GetInterface; #endif // #if defined(AUTO_LINK_DX12) +// Command line flags +static bool g_ShowVersionAndQuit = false; +static bool g_ShowCommandLineSyntaxAndQuit = false; +static bool g_ShowCommandLineSyntaxAndFail = false; static bool g_ListAdapters = false; static bool g_ShowAllAdapters = true; static bool g_SkipSoftwareAdapter = true; +static bool g_UseJsonOutput = false; +static bool g_UseJsonPrettyPrint = true; +static bool g_OutputToFile = false; static bool g_PrintFormats = false; static bool g_PrintMetaCommands = false; static bool g_PrintEnums = false; @@ -93,6 +100,10 @@ static bool g_EnableExperimental = false; #endif static bool g_ForceVendorAPI = false; static bool g_WARP = false; +static std::wstring g_OutputFilePath; + +// Derived flags +static bool g_PrintAdaptersAsArray = true; static wstring LuidToStr(LUID value) { @@ -103,334 +114,327 @@ static wstring LuidToStr(LUID value) static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS(const D3D12_FEATURE_DATA_D3D12_OPTIONS& options) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS"); - Print_BOOL( L"DoublePrecisionFloatShaderOps", options.DoublePrecisionFloatShaderOps); - Print_BOOL( L"OutputMergerLogicOp", options.OutputMergerLogicOp); - PrintEnum( L"MinPrecisionSupport", options.MinPrecisionSupport, Enum_D3D12_SHADER_MIN_PRECISION_SUPPORT); - PrintEnum( L"TiledResourcesTier", options.TiledResourcesTier, Enum_D3D12_TILED_RESOURCES_TIER); - PrintEnum( L"ResourceBindingTier", options.ResourceBindingTier, Enum_D3D12_RESOURCE_BINDING_TIER); - Print_BOOL( L"PSSpecifiedStencilRefSupported", options.PSSpecifiedStencilRefSupported); - Print_BOOL( L"TypedUAVLoadAdditionalFormats", options.TypedUAVLoadAdditionalFormats); - Print_BOOL( L"ROVsSupported", options.ROVsSupported); - PrintEnum( L"ConservativeRasterizationTier", options.ConservativeRasterizationTier, Enum_D3D12_CONSERVATIVE_RASTERIZATION_TIER); - Print_uint32(L"MaxGPUVirtualAddressBitsPerResource", options.MaxGPUVirtualAddressBitsPerResource); - Print_BOOL( L"StandardSwizzle64KBSupported", options.StandardSwizzle64KBSupported); - PrintEnum( L"CrossNodeSharingTier", options.CrossNodeSharingTier, Enum_D3D12_CROSS_NODE_SHARING_TIER); - Print_BOOL( L"CrossAdapterRowMajorTextureSupported", options.CrossAdapterRowMajorTextureSupported); - Print_BOOL( L"VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation", options.VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation); - PrintEnum( L"ResourceHeapTier", options.ResourceHeapTier, Enum_D3D12_RESOURCE_HEAP_TIER); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS"); + ReportFormatter::GetInstance().AddFieldBool(L"DoublePrecisionFloatShaderOps", options.DoublePrecisionFloatShaderOps); + ReportFormatter::GetInstance().AddFieldBool(L"OutputMergerLogicOp", options.OutputMergerLogicOp); + ReportFormatter::GetInstance().AddFieldEnum(L"MinPrecisionSupport", options.MinPrecisionSupport, Enum_D3D12_SHADER_MIN_PRECISION_SUPPORT); + ReportFormatter::GetInstance().AddFieldEnum(L"TiledResourcesTier", options.TiledResourcesTier, Enum_D3D12_TILED_RESOURCES_TIER); + ReportFormatter::GetInstance().AddFieldEnum(L"ResourceBindingTier", options.ResourceBindingTier, Enum_D3D12_RESOURCE_BINDING_TIER); + ReportFormatter::GetInstance().AddFieldBool(L"PSSpecifiedStencilRefSupported", options.PSSpecifiedStencilRefSupported); + ReportFormatter::GetInstance().AddFieldBool(L"TypedUAVLoadAdditionalFormats", options.TypedUAVLoadAdditionalFormats); + ReportFormatter::GetInstance().AddFieldBool(L"ROVsSupported", options.ROVsSupported); + ReportFormatter::GetInstance().AddFieldEnum(L"ConservativeRasterizationTier", options.ConservativeRasterizationTier, Enum_D3D12_CONSERVATIVE_RASTERIZATION_TIER); + ReportFormatter::GetInstance().AddFieldUint32(L"MaxGPUVirtualAddressBitsPerResource", options.MaxGPUVirtualAddressBitsPerResource); + ReportFormatter::GetInstance().AddFieldBool(L"StandardSwizzle64KBSupported", options.StandardSwizzle64KBSupported); + ReportFormatter::GetInstance().AddFieldEnum(L"CrossNodeSharingTier", options.CrossNodeSharingTier, Enum_D3D12_CROSS_NODE_SHARING_TIER); + ReportFormatter::GetInstance().AddFieldBool(L"CrossAdapterRowMajorTextureSupported", options.CrossAdapterRowMajorTextureSupported); + ReportFormatter::GetInstance().AddFieldBool(L"VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation", options.VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation); + ReportFormatter::GetInstance().AddFieldEnum(L"ResourceHeapTier", options.ResourceHeapTier, Enum_D3D12_RESOURCE_HEAP_TIER); } static void Print_D3D12_FEATURE_DATA_ARCHITECTURE(const D3D12_FEATURE_DATA_ARCHITECTURE& architecture) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_ARCHITECTURE"); - Print_uint32(L"NodeIndex", architecture.NodeIndex); - Print_BOOL (L"TileBasedRenderer", architecture.TileBasedRenderer); - Print_BOOL (L"UMA", architecture.UMA); - Print_BOOL (L"CacheCoherentUMA", architecture.CacheCoherentUMA); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_ARCHITECTURE"); + ReportFormatter::GetInstance().AddFieldUint32(L"NodeIndex", architecture.NodeIndex); + ReportFormatter::GetInstance().AddFieldBool(L"TileBasedRenderer", architecture.TileBasedRenderer); + ReportFormatter::GetInstance().AddFieldBool(L"UMA", architecture.UMA); + ReportFormatter::GetInstance().AddFieldBool(L"CacheCoherentUMA", architecture.CacheCoherentUMA); } static void Print_D3D12_FEATURE_DATA_ARCHITECTURE1(const D3D12_FEATURE_DATA_ARCHITECTURE1& architecture1) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_ARCHITECTURE1"); - Print_uint32(L"NodeIndex", architecture1.NodeIndex); - Print_BOOL (L"TileBasedRenderer", architecture1.TileBasedRenderer); - Print_BOOL (L"UMA", architecture1.UMA); - Print_BOOL (L"CacheCoherentUMA", architecture1.CacheCoherentUMA); - Print_BOOL (L"IsolatedMMU", architecture1.IsolatedMMU); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_ARCHITECTURE1"); + ReportFormatter::GetInstance().AddFieldUint32(L"NodeIndex", architecture1.NodeIndex); + ReportFormatter::GetInstance().AddFieldBool(L"TileBasedRenderer", architecture1.TileBasedRenderer); + ReportFormatter::GetInstance().AddFieldBool(L"UMA", architecture1.UMA); + ReportFormatter::GetInstance().AddFieldBool(L"CacheCoherentUMA", architecture1.CacheCoherentUMA); + ReportFormatter::GetInstance().AddFieldBool(L"IsolatedMMU", architecture1.IsolatedMMU); } static void Print_D3D12_FEATURE_DATA_FEATURE_LEVELS(const D3D12_FEATURE_DATA_FEATURE_LEVELS& featureLevels) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_FEATURE_LEVELS"); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_FEATURE_LEVELS"); -#if 0 // TODO Is this an output parameter or not? How to correctly query and print it??? - Print_uint32(L"NumFeatureLevels", featureLevels.NumFeatureLevels); - BeginArray(); - for(uint32_t i = 0; i < featureLevels.NumFeatureLevels; ++i) - { - PrintEnum(L"pFeatureLevelsRequested", featureLevels.pFeatureLevelsRequested[i], Enum_D3D_FEATURE_LEVEL); - StepArray(); - } - EndArray(); -#endif - PrintEnum(L"MaxSupportedFeatureLevel", featureLevels.MaxSupportedFeatureLevel, Enum_D3D_FEATURE_LEVEL); + // NumFeatureLevels and pFeatureLevelsRequested are IN parameters + // They let the app to specify what enum values does the app expect + // So same API can be used when new feature levels are added in the future + // No need to print those IN parameters here + ReportFormatter::GetInstance().AddFieldEnum(L"MaxSupportedFeatureLevel", featureLevels.MaxSupportedFeatureLevel, Enum_D3D_FEATURE_LEVEL); } static void Print_D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT(const D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT& virtualAddressSupport) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT"); - Print_uint32(L"MaxGPUVirtualAddressBitsPerResource", virtualAddressSupport.MaxGPUVirtualAddressBitsPerResource); - Print_uint32(L"MaxGPUVirtualAddressBitsPerProcess", virtualAddressSupport.MaxGPUVirtualAddressBitsPerProcess); - + ReportScopeObject scope(L"D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT"); + ReportFormatter::GetInstance().AddFieldUint32(L"MaxGPUVirtualAddressBitsPerResource", virtualAddressSupport.MaxGPUVirtualAddressBitsPerResource); + ReportFormatter::GetInstance().AddFieldUint32(L"MaxGPUVirtualAddressBitsPerProcess", virtualAddressSupport.MaxGPUVirtualAddressBitsPerProcess); } static void Print_D3D12_FEATURE_DATA_SHADER_MODEL(const D3D12_FEATURE_DATA_SHADER_MODEL& shaderModel) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_SHADER_MODEL"); - PrintEnum(L"HighestShaderModel", shaderModel.HighestShaderModel, Enum_D3D_SHADER_MODEL); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_SHADER_MODEL"); + ReportFormatter::GetInstance().AddFieldEnum(L"HighestShaderModel", shaderModel.HighestShaderModel, Enum_D3D_SHADER_MODEL); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS1(const D3D12_FEATURE_DATA_D3D12_OPTIONS1& options1) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS1"); - Print_BOOL (L"WaveOps", options1.WaveOps); - Print_uint32(L"WaveLaneCountMin", options1.WaveLaneCountMin); - Print_uint32(L"WaveLaneCountMax", options1.WaveLaneCountMax); - Print_uint32(L"TotalLaneCount", options1.TotalLaneCount); - Print_BOOL (L"ExpandedComputeResourceStates", options1.ExpandedComputeResourceStates); - Print_BOOL (L"Int64ShaderOps", options1.Int64ShaderOps); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS1"); + ReportFormatter::GetInstance().AddFieldBool(L"WaveOps", options1.WaveOps); + ReportFormatter::GetInstance().AddFieldUint32(L"WaveLaneCountMin", options1.WaveLaneCountMin); + ReportFormatter::GetInstance().AddFieldUint32(L"WaveLaneCountMax", options1.WaveLaneCountMax); + ReportFormatter::GetInstance().AddFieldUint32(L"TotalLaneCount", options1.TotalLaneCount); + ReportFormatter::GetInstance().AddFieldBool(L"ExpandedComputeResourceStates", options1.ExpandedComputeResourceStates); + ReportFormatter::GetInstance().AddFieldBool(L"Int64ShaderOps", options1.Int64ShaderOps); } static void Print_D3D12_FEATURE_DATA_ROOT_SIGNATURE(const D3D12_FEATURE_DATA_ROOT_SIGNATURE& rootSignature) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_ROOT_SIGNATURE"); - PrintEnum(L"HighestVersion", rootSignature.HighestVersion, Enum_D3D_ROOT_SIGNATURE_VERSION); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_ROOT_SIGNATURE"); + ReportFormatter::GetInstance().AddFieldEnum(L"HighestVersion", rootSignature.HighestVersion, Enum_D3D_ROOT_SIGNATURE_VERSION); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS2(const D3D12_FEATURE_DATA_D3D12_OPTIONS2& options2) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS2"); - Print_BOOL(L"DepthBoundsTestSupported", options2.DepthBoundsTestSupported); - PrintEnum (L"ProgrammableSamplePositionsTier", options2.ProgrammableSamplePositionsTier, Enum_D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS2"); + ReportFormatter::GetInstance().AddFieldBool(L"DepthBoundsTestSupported", options2.DepthBoundsTestSupported); + ReportFormatter::GetInstance().AddFieldEnum(L"ProgrammableSamplePositionsTier", options2.ProgrammableSamplePositionsTier, Enum_D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER); } static void Print_D3D12_FEATURE_DATA_SHADER_CACHE(const D3D12_FEATURE_DATA_SHADER_CACHE& shaderCache) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_SHADER_CACHE"); - PrintFlags(L"SupportFlags", shaderCache.SupportFlags, Enum_D3D12_SHADER_CACHE_SUPPORT_FLAGS); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_SHADER_CACHE"); + ReportFormatter::GetInstance().AddFieldFlags(L"SupportFlags", shaderCache.SupportFlags, Enum_D3D12_SHADER_CACHE_SUPPORT_FLAGS); } static void Print_D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY(const std::array& commandQueuePriority) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY"); - Print_BOOL(L"TYPE_DIRECT.PRIORITY_NORMAL.PriorityForTypeIsSupported", commandQueuePriority[0]); - Print_BOOL(L"TYPE_DIRECT.PRIORITY_HIGH.PriorityForTypeIsSupported", commandQueuePriority[1]); - Print_BOOL(L"TYPE_DIRECT.PRIORITY_GLOBAL_REALTIME.PriorityForTypeIsSupported", commandQueuePriority[2]); - Print_BOOL(L"TYPE_COMPUTE.PRIORITY_NORMAL.PriorityForTypeIsSupported", commandQueuePriority[3]); - Print_BOOL(L"TYPE_COMPUTE.PRIORITY_HIGH.PriorityForTypeIsSupported", commandQueuePriority[4]); - Print_BOOL(L"TYPE_COMPUTE.PRIORITY_GLOBAL_REALTIME.PriorityForTypeIsSupported", commandQueuePriority[5]); - Print_BOOL(L"TYPE_COPY.PRIORITY_NORMAL.PriorityForTypeIsSupported", commandQueuePriority[6]); - Print_BOOL(L"TYPE_COPY.PRIORITY_HIGH.PriorityForTypeIsSupported", commandQueuePriority[7]); - Print_BOOL(L"TYPE_COPY.PRIORITY_GLOBAL_REALTIME.PriorityForTypeIsSupported", commandQueuePriority[8]); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY"); + ReportFormatter::GetInstance().AddFieldBool(L"TYPE_DIRECT.PRIORITY_NORMAL.PriorityForTypeIsSupported", commandQueuePriority[0]); + ReportFormatter::GetInstance().AddFieldBool(L"TYPE_DIRECT.PRIORITY_HIGH.PriorityForTypeIsSupported", commandQueuePriority[1]); + ReportFormatter::GetInstance().AddFieldBool(L"TYPE_DIRECT.PRIORITY_GLOBAL_REALTIME.PriorityForTypeIsSupported", commandQueuePriority[2]); + ReportFormatter::GetInstance().AddFieldBool(L"TYPE_COMPUTE.PRIORITY_NORMAL.PriorityForTypeIsSupported", commandQueuePriority[3]); + ReportFormatter::GetInstance().AddFieldBool(L"TYPE_COMPUTE.PRIORITY_HIGH.PriorityForTypeIsSupported", commandQueuePriority[4]); + ReportFormatter::GetInstance().AddFieldBool(L"TYPE_COMPUTE.PRIORITY_GLOBAL_REALTIME.PriorityForTypeIsSupported", commandQueuePriority[5]); + ReportFormatter::GetInstance().AddFieldBool(L"TYPE_COPY.PRIORITY_NORMAL.PriorityForTypeIsSupported", commandQueuePriority[6]); + ReportFormatter::GetInstance().AddFieldBool(L"TYPE_COPY.PRIORITY_HIGH.PriorityForTypeIsSupported", commandQueuePriority[7]); + ReportFormatter::GetInstance().AddFieldBool(L"TYPE_COPY.PRIORITY_GLOBAL_REALTIME.PriorityForTypeIsSupported", commandQueuePriority[8]); } static void Print_D3D12_FEATURE_DATA_SERIALIZATION(const D3D12_FEATURE_DATA_SERIALIZATION& serialization) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_SERIALIZATION"); - PrintEnum(L"HeapSerializationTier", serialization.HeapSerializationTier, Enum_D3D12_HEAP_SERIALIZATION_TIER); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_SERIALIZATION"); + ReportFormatter::GetInstance().AddFieldEnum(L"HeapSerializationTier", serialization.HeapSerializationTier, Enum_D3D12_HEAP_SERIALIZATION_TIER); } static void Print_D3D12_FEATURE_CROSS_NODE(const D3D12_FEATURE_DATA_CROSS_NODE& crossNode) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_CROSS_NODE"); - PrintEnum(L"SharingTier", crossNode.SharingTier, Enum_D3D12_CROSS_NODE_SHARING_TIER); - Print_BOOL(L"AtomicShaderInstructions", crossNode.AtomicShaderInstructions); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_CROSS_NODE"); + ReportFormatter::GetInstance().AddFieldEnum(L"SharingTier", crossNode.SharingTier, Enum_D3D12_CROSS_NODE_SHARING_TIER); + ReportFormatter::GetInstance().AddFieldBool(L"AtomicShaderInstructions", crossNode.AtomicShaderInstructions); } static void Print_D3D12_FEATURE_PREDICATION(const D3D12_FEATURE_DATA_PREDICATION& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_PREDICATION"); - Print_BOOL(L"Supported", o.Supported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_PREDICATION"); + ReportFormatter::GetInstance().AddFieldBool(L"Supported", o.Supported); } static void Print_D3D12_FEATURE_HARDWARE_COPY(const D3D12_FEATURE_DATA_HARDWARE_COPY& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_HARDWARE_COPY"); - Print_BOOL(L"Supported", o.Supported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_HARDWARE_COPY"); + ReportFormatter::GetInstance().AddFieldBool(L"Supported", o.Supported); } #ifdef USE_PREVIEW_AGILITY_SDK static void Print_D3D12_FEATURE_DATA_APPLICATION_SPECIFIC_DRIVER_STATE(const D3D12_FEATURE_DATA_APPLICATION_SPECIFIC_DRIVER_STATE& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_APPLICATION_SPECIFIC_DRIVER_STATE"); - Print_BOOL(L"Supported", o.Supported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_APPLICATION_SPECIFIC_DRIVER_STATE"); + ReportFormatter::GetInstance().AddFieldBool(L"Supported", o.Supported); } #endif // #ifdef USE_PREVIEW_AGILITY_SDK static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS3(const D3D12_FEATURE_DATA_D3D12_OPTIONS3& options3) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS3"); - Print_BOOL(L"CopyQueueTimestampQueriesSupported", options3.CopyQueueTimestampQueriesSupported); - Print_BOOL(L"CastingFullyTypedFormatSupported", options3.CastingFullyTypedFormatSupported); - PrintFlags(L"WriteBufferImmediateSupportFlags", options3.WriteBufferImmediateSupportFlags, Enum_D3D12_COMMAND_LIST_SUPPORT_FLAGS); - PrintEnum (L"ViewInstancingTier", options3.ViewInstancingTier, Enum_D3D12_VIEW_INSTANCING_TIER); - Print_BOOL(L"BarycentricsSupported", options3.BarycentricsSupported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS3"); + ReportFormatter::GetInstance().AddFieldBool(L"CopyQueueTimestampQueriesSupported", options3.CopyQueueTimestampQueriesSupported); + ReportFormatter::GetInstance().AddFieldBool(L"CastingFullyTypedFormatSupported", options3.CastingFullyTypedFormatSupported); + ReportFormatter::GetInstance().AddFieldFlags(L"WriteBufferImmediateSupportFlags", options3.WriteBufferImmediateSupportFlags, Enum_D3D12_COMMAND_LIST_SUPPORT_FLAGS); + ReportFormatter::GetInstance().AddFieldEnum(L"ViewInstancingTier", options3.ViewInstancingTier, Enum_D3D12_VIEW_INSTANCING_TIER); + ReportFormatter::GetInstance().AddFieldBool(L"BarycentricsSupported", options3.BarycentricsSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS4(const D3D12_FEATURE_DATA_D3D12_OPTIONS4& options4) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS4"); - Print_BOOL(L"MSAA64KBAlignedTextureSupported", options4.MSAA64KBAlignedTextureSupported); - PrintEnum(L"SharedResourceCompatibilityTier", options4.SharedResourceCompatibilityTier, Enum_D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER); - Print_BOOL(L"Native16BitShaderOpsSupported", options4.Native16BitShaderOpsSupported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS4"); + ReportFormatter::GetInstance().AddFieldBool(L"MSAA64KBAlignedTextureSupported", options4.MSAA64KBAlignedTextureSupported); + ReportFormatter::GetInstance().AddFieldEnum(L"SharedResourceCompatibilityTier", options4.SharedResourceCompatibilityTier, Enum_D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER); + ReportFormatter::GetInstance().AddFieldBool(L"Native16BitShaderOpsSupported", options4.Native16BitShaderOpsSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS5(const D3D12_FEATURE_DATA_D3D12_OPTIONS5& options5) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS5"); - Print_BOOL(L"SRVOnlyTiledResourceTier3", options5.SRVOnlyTiledResourceTier3); - PrintEnum(L"RenderPassesTier", options5.RenderPassesTier, Enum_D3D12_RENDER_PASS_TIER); - PrintEnum(L"RaytracingTier", options5.RaytracingTier, Enum_D3D12_RAYTRACING_TIER); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS5"); + ReportFormatter::GetInstance().AddFieldBool(L"SRVOnlyTiledResourceTier3", options5.SRVOnlyTiledResourceTier3); + ReportFormatter::GetInstance().AddFieldEnum(L"RenderPassesTier", options5.RenderPassesTier, Enum_D3D12_RENDER_PASS_TIER); + ReportFormatter::GetInstance().AddFieldEnum(L"RaytracingTier", options5.RaytracingTier, Enum_D3D12_RAYTRACING_TIER); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS6(const D3D12_FEATURE_DATA_D3D12_OPTIONS6& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS6"); - Print_BOOL(L"AdditionalShadingRatesSupported", o.AdditionalShadingRatesSupported); - Print_BOOL(L"PerPrimitiveShadingRateSupportedWithViewportIndexing", o.PerPrimitiveShadingRateSupportedWithViewportIndexing); - PrintEnum(L"VariableShadingRateTier", o.VariableShadingRateTier, Enum_D3D12_VARIABLE_SHADING_RATE_TIER); - Print_uint32(L"ShadingRateImageTileSize", o.ShadingRateImageTileSize); - Print_BOOL(L"BackgroundProcessingSupported", o.BackgroundProcessingSupported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS6"); + ReportFormatter::GetInstance().AddFieldBool(L"AdditionalShadingRatesSupported", o.AdditionalShadingRatesSupported); + ReportFormatter::GetInstance().AddFieldBool(L"PerPrimitiveShadingRateSupportedWithViewportIndexing", o.PerPrimitiveShadingRateSupportedWithViewportIndexing); + ReportFormatter::GetInstance().AddFieldEnum(L"VariableShadingRateTier", o.VariableShadingRateTier, Enum_D3D12_VARIABLE_SHADING_RATE_TIER); + ReportFormatter::GetInstance().AddFieldUint32(L"ShadingRateImageTileSize", o.ShadingRateImageTileSize); + ReportFormatter::GetInstance().AddFieldBool(L"BackgroundProcessingSupported", o.BackgroundProcessingSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS7(const D3D12_FEATURE_DATA_D3D12_OPTIONS7& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS7"); - PrintEnum(L"MeshShaderTier", o.MeshShaderTier, Enum_D3D12_MESH_SHADER_TIER); - PrintEnum(L"SamplerFeedbackTier", o.SamplerFeedbackTier, Enum_D3D12_SAMPLER_FEEDBACK_TIER); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS7"); + ReportFormatter::GetInstance().AddFieldEnum(L"MeshShaderTier", o.MeshShaderTier, Enum_D3D12_MESH_SHADER_TIER); + ReportFormatter::GetInstance().AddFieldEnum(L"SamplerFeedbackTier", o.SamplerFeedbackTier, Enum_D3D12_SAMPLER_FEEDBACK_TIER); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS8(const D3D12_FEATURE_DATA_D3D12_OPTIONS8& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS8"); - Print_BOOL(L"UnalignedBlockTexturesSupported", o.UnalignedBlockTexturesSupported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS8"); + ReportFormatter::GetInstance().AddFieldBool(L"UnalignedBlockTexturesSupported", o.UnalignedBlockTexturesSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS9(const D3D12_FEATURE_DATA_D3D12_OPTIONS9& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS9"); - Print_BOOL(L"MeshShaderPipelineStatsSupported", o.MeshShaderPipelineStatsSupported); - Print_BOOL(L"MeshShaderSupportsFullRangeRenderTargetArrayIndex", o.MeshShaderSupportsFullRangeRenderTargetArrayIndex); - Print_BOOL(L"AtomicInt64OnTypedResourceSupported", o.AtomicInt64OnTypedResourceSupported); - Print_BOOL(L"AtomicInt64OnGroupSharedSupported", o.AtomicInt64OnGroupSharedSupported); - Print_BOOL(L"DerivativesInMeshAndAmplificationShadersSupported", o.DerivativesInMeshAndAmplificationShadersSupported); - PrintEnum(L"WaveMMATier", o.WaveMMATier, Enum_D3D12_WAVE_MMA_TIER); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS9"); + ReportFormatter::GetInstance().AddFieldBool(L"MeshShaderPipelineStatsSupported", o.MeshShaderPipelineStatsSupported); + ReportFormatter::GetInstance().AddFieldBool(L"MeshShaderSupportsFullRangeRenderTargetArrayIndex", o.MeshShaderSupportsFullRangeRenderTargetArrayIndex); + ReportFormatter::GetInstance().AddFieldBool(L"AtomicInt64OnTypedResourceSupported", o.AtomicInt64OnTypedResourceSupported); + ReportFormatter::GetInstance().AddFieldBool(L"AtomicInt64OnGroupSharedSupported", o.AtomicInt64OnGroupSharedSupported); + ReportFormatter::GetInstance().AddFieldBool(L"DerivativesInMeshAndAmplificationShadersSupported", o.DerivativesInMeshAndAmplificationShadersSupported); + ReportFormatter::GetInstance().AddFieldEnum(L"WaveMMATier", o.WaveMMATier, Enum_D3D12_WAVE_MMA_TIER); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS10(const D3D12_FEATURE_DATA_D3D12_OPTIONS10& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS10"); - Print_BOOL(L"VariableRateShadingSumCombinerSupported", o.VariableRateShadingSumCombinerSupported); - Print_BOOL(L"MeshShaderPerPrimitiveShadingRateSupported", o.MeshShaderPerPrimitiveShadingRateSupported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS10"); + ReportFormatter::GetInstance().AddFieldBool(L"VariableRateShadingSumCombinerSupported", o.VariableRateShadingSumCombinerSupported); + ReportFormatter::GetInstance().AddFieldBool(L"MeshShaderPerPrimitiveShadingRateSupported", o.MeshShaderPerPrimitiveShadingRateSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS11(const D3D12_FEATURE_DATA_D3D12_OPTIONS11& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS11"); - Print_BOOL(L"AtomicInt64OnDescriptorHeapResourceSupported", o.AtomicInt64OnDescriptorHeapResourceSupported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS11"); + ReportFormatter::GetInstance().AddFieldBool(L"AtomicInt64OnDescriptorHeapResourceSupported", o.AtomicInt64OnDescriptorHeapResourceSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS12(const D3D12_FEATURE_DATA_D3D12_OPTIONS12& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS12"); - PrintEnum(L"MSPrimitivesPipelineStatisticIncludesCulledPrimitives", o.MSPrimitivesPipelineStatisticIncludesCulledPrimitives, Enum_D3D12_TRI_STATE, true); - Print_BOOL(L"EnhancedBarriersSupported", o.EnhancedBarriersSupported); - Print_BOOL(L"RelaxedFormatCastingSupported", o.RelaxedFormatCastingSupported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS12"); + ReportFormatter::GetInstance().AddFieldEnumSigned(L"MSPrimitivesPipelineStatisticIncludesCulledPrimitives", o.MSPrimitivesPipelineStatisticIncludesCulledPrimitives, Enum_D3D12_TRI_STATE); + ReportFormatter::GetInstance().AddFieldBool(L"EnhancedBarriersSupported", o.EnhancedBarriersSupported); + ReportFormatter::GetInstance().AddFieldBool(L"RelaxedFormatCastingSupported", o.RelaxedFormatCastingSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS13(const D3D12_FEATURE_DATA_D3D12_OPTIONS13& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS13"); - Print_BOOL(L"UnrestrictedBufferTextureCopyPitchSupported", o.UnrestrictedBufferTextureCopyPitchSupported); - Print_BOOL(L"UnrestrictedVertexElementAlignmentSupported", o.UnrestrictedVertexElementAlignmentSupported); - Print_BOOL(L"InvertedViewportHeightFlipsYSupported", o.InvertedViewportHeightFlipsYSupported); - Print_BOOL(L"InvertedViewportDepthFlipsZSupported", o.InvertedViewportDepthFlipsZSupported); - Print_BOOL(L"TextureCopyBetweenDimensionsSupported", o.TextureCopyBetweenDimensionsSupported); - Print_BOOL(L"AlphaBlendFactorSupported", o.AlphaBlendFactorSupported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS13"); + ReportFormatter::GetInstance().AddFieldBool(L"UnrestrictedBufferTextureCopyPitchSupported", o.UnrestrictedBufferTextureCopyPitchSupported); + ReportFormatter::GetInstance().AddFieldBool(L"UnrestrictedVertexElementAlignmentSupported", o.UnrestrictedVertexElementAlignmentSupported); + ReportFormatter::GetInstance().AddFieldBool(L"InvertedViewportHeightFlipsYSupported", o.InvertedViewportHeightFlipsYSupported); + ReportFormatter::GetInstance().AddFieldBool(L"InvertedViewportDepthFlipsZSupported", o.InvertedViewportDepthFlipsZSupported); + ReportFormatter::GetInstance().AddFieldBool(L"TextureCopyBetweenDimensionsSupported", o.TextureCopyBetweenDimensionsSupported); + ReportFormatter::GetInstance().AddFieldBool(L"AlphaBlendFactorSupported", o.AlphaBlendFactorSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS14(const D3D12_FEATURE_DATA_D3D12_OPTIONS14& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS14"); - Print_BOOL(L"AdvancedTextureOpsSupported", o.AdvancedTextureOpsSupported); - Print_BOOL(L"WriteableMSAATexturesSupported", o.WriteableMSAATexturesSupported); - Print_BOOL(L"IndependentFrontAndBackStencilRefMaskSupported", o.IndependentFrontAndBackStencilRefMaskSupported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS14"); + ReportFormatter::GetInstance().AddFieldBool(L"AdvancedTextureOpsSupported", o.AdvancedTextureOpsSupported); + ReportFormatter::GetInstance().AddFieldBool(L"WriteableMSAATexturesSupported", o.WriteableMSAATexturesSupported); + ReportFormatter::GetInstance().AddFieldBool(L"IndependentFrontAndBackStencilRefMaskSupported", o.IndependentFrontAndBackStencilRefMaskSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS15(const D3D12_FEATURE_DATA_D3D12_OPTIONS15& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS15"); - Print_BOOL(L"TriangleFanSupported", o.TriangleFanSupported); - Print_BOOL(L"DynamicIndexBufferStripCutSupported", o.DynamicIndexBufferStripCutSupported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS15"); + ReportFormatter::GetInstance().AddFieldBool(L"TriangleFanSupported", o.TriangleFanSupported); + ReportFormatter::GetInstance().AddFieldBool(L"DynamicIndexBufferStripCutSupported", o.DynamicIndexBufferStripCutSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS16(const D3D12_FEATURE_DATA_D3D12_OPTIONS16& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS16"); - Print_BOOL(L"DynamicDepthBiasSupported", o.DynamicDepthBiasSupported); - Print_BOOL(L"GPUUploadHeapSupported", o.GPUUploadHeapSupported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS16"); + ReportFormatter::GetInstance().AddFieldBool(L"DynamicDepthBiasSupported", o.DynamicDepthBiasSupported); + ReportFormatter::GetInstance().AddFieldBool(L"GPUUploadHeapSupported", o.GPUUploadHeapSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS17(const D3D12_FEATURE_DATA_D3D12_OPTIONS17& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS17"); - Print_BOOL(L"NonNormalizedCoordinateSamplersSupported", o.NonNormalizedCoordinateSamplersSupported); - Print_BOOL(L"ManualWriteTrackingResourceSupported", o.ManualWriteTrackingResourceSupported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS17"); + ReportFormatter::GetInstance().AddFieldBool(L"NonNormalizedCoordinateSamplersSupported", o.NonNormalizedCoordinateSamplersSupported); + ReportFormatter::GetInstance().AddFieldBool(L"ManualWriteTrackingResourceSupported", o.ManualWriteTrackingResourceSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS18(const D3D12_FEATURE_DATA_D3D12_OPTIONS18& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS18"); - Print_BOOL(L"RenderPassesValid", o.RenderPassesValid); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS18"); + ReportFormatter::GetInstance().AddFieldBool(L"RenderPassesValid", o.RenderPassesValid); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS19(const D3D12_FEATURE_DATA_D3D12_OPTIONS19& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS19"); - Print_BOOL(L"MismatchingOutputDimensionsSupported", o.MismatchingOutputDimensionsSupported); - Print_uint32(L"SupportedSampleCountsWithNoOutputs", o.SupportedSampleCountsWithNoOutputs); - Print_BOOL(L"PointSamplingAddressesNeverRoundUp", o.PointSamplingAddressesNeverRoundUp); - Print_BOOL(L"RasterizerDesc2Supported", o.RasterizerDesc2Supported); - Print_BOOL(L"NarrowQuadrilateralLinesSupported", o.NarrowQuadrilateralLinesSupported); - Print_BOOL(L"AnisoFilterWithPointMipSupported", o.AnisoFilterWithPointMipSupported); - Print_uint32(L"MaxSamplerDescriptorHeapSize", o.MaxSamplerDescriptorHeapSize); - Print_uint32(L"MaxSamplerDescriptorHeapSizeWithStaticSamplers", o.MaxSamplerDescriptorHeapSizeWithStaticSamplers); - Print_uint32(L"MaxViewDescriptorHeapSize", o.MaxViewDescriptorHeapSize); - Print_BOOL(L"ComputeOnlyCustomHeapSupported", o.ComputeOnlyCustomHeapSupported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS19"); + ReportFormatter::GetInstance().AddFieldBool(L"MismatchingOutputDimensionsSupported", o.MismatchingOutputDimensionsSupported); + ReportFormatter::GetInstance().AddFieldUint32(L"SupportedSampleCountsWithNoOutputs", o.SupportedSampleCountsWithNoOutputs); + ReportFormatter::GetInstance().AddFieldBool(L"PointSamplingAddressesNeverRoundUp", o.PointSamplingAddressesNeverRoundUp); + ReportFormatter::GetInstance().AddFieldBool(L"RasterizerDesc2Supported", o.RasterizerDesc2Supported); + ReportFormatter::GetInstance().AddFieldBool(L"NarrowQuadrilateralLinesSupported", o.NarrowQuadrilateralLinesSupported); + ReportFormatter::GetInstance().AddFieldBool(L"AnisoFilterWithPointMipSupported", o.AnisoFilterWithPointMipSupported); + ReportFormatter::GetInstance().AddFieldUint32(L"MaxSamplerDescriptorHeapSize", o.MaxSamplerDescriptorHeapSize); + ReportFormatter::GetInstance().AddFieldUint32(L"MaxSamplerDescriptorHeapSizeWithStaticSamplers", o.MaxSamplerDescriptorHeapSizeWithStaticSamplers); + ReportFormatter::GetInstance().AddFieldUint32(L"MaxViewDescriptorHeapSize", o.MaxViewDescriptorHeapSize); + ReportFormatter::GetInstance().AddFieldBool(L"ComputeOnlyCustomHeapSupported", o.ComputeOnlyCustomHeapSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS20(const D3D12_FEATURE_DATA_D3D12_OPTIONS20& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS20"); - Print_BOOL(L"ComputeOnlyWriteWatchSupported", o.ComputeOnlyWriteWatchSupported); - PrintEnum(L"RecreateAtTier", o.RecreateAtTier, Enum_D3D12_RECREATE_AT_TIER); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS20"); + ReportFormatter::GetInstance().AddFieldBool(L"ComputeOnlyWriteWatchSupported", o.ComputeOnlyWriteWatchSupported); + ReportFormatter::GetInstance().AddFieldEnum(L"RecreateAtTier", o.RecreateAtTier, Enum_D3D12_RECREATE_AT_TIER); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS21(const D3D12_FEATURE_DATA_D3D12_OPTIONS21& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_D3D12_OPTIONS21"); - PrintEnum(L"WorkGraphsTier", o.WorkGraphsTier, Enum_D3D12_WORK_GRAPHS_TIER); - PrintEnum(L"ExecuteIndirectTier", o.ExecuteIndirectTier, Enum_D3D12_EXECUTE_INDIRECT_TIER); - Print_BOOL(L"SampleCmpGradientAndBiasSupported", o.SampleCmpGradientAndBiasSupported); - Print_BOOL(L"ExtendedCommandInfoSupported", o.ExtendedCommandInfoSupported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS21"); + ReportFormatter::GetInstance().AddFieldEnum(L"WorkGraphsTier", o.WorkGraphsTier, Enum_D3D12_WORK_GRAPHS_TIER); + ReportFormatter::GetInstance().AddFieldEnum(L"ExecuteIndirectTier", o.ExecuteIndirectTier, Enum_D3D12_EXECUTE_INDIRECT_TIER); + ReportFormatter::GetInstance().AddFieldBool(L"SampleCmpGradientAndBiasSupported", o.SampleCmpGradientAndBiasSupported); + ReportFormatter::GetInstance().AddFieldBool(L"ExtendedCommandInfoSupported", o.ExtendedCommandInfoSupported); } static void Print_D3D12_FEATURE_DATA_BYTECODE_BYPASS_HASH_SUPPORTED(const D3D12_FEATURE_DATA_BYTECODE_BYPASS_HASH_SUPPORTED& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_BYTECODE_BYPASS_HASH_SUPPORTED"); - Print_BOOL(L"Supported", o.Supported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_BYTECODE_BYPASS_HASH_SUPPORTED"); + ReportFormatter::GetInstance().AddFieldBool(L"Supported", o.Supported); } #ifdef USE_PREVIEW_AGILITY_SDK static void Print_D3D12_FEATURE_DATA_TIGHT_ALIGNMENT(const D3D12_FEATURE_DATA_TIGHT_ALIGNMENT& o) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_TIGHT_ALIGNMENT"); - PrintEnum(L"SupportTier", o.SupportTier, Enum_D3D12_TIGHT_ALIGNMENT_TIER); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_TIGHT_ALIGNMENT"); + ReportFormatter::GetInstance().AddFieldEnum(L"SupportTier", o.SupportTier, Enum_D3D12_TIGHT_ALIGNMENT_TIER); } #endif // #ifdef USE_PREVIEW_AGILITY_SDK static void Print_D3D12_FEATURE_DATA_EXISTING_HEAPS(const D3D12_FEATURE_DATA_EXISTING_HEAPS& existingHeaps) { - ScopedStructRegion region(L"D3D12_FEATURE_DATA_EXISTING_HEAPS"); - Print_BOOL(L"Supported", existingHeaps.Supported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_EXISTING_HEAPS"); + ReportFormatter::GetInstance().AddFieldBool(L"Supported", existingHeaps.Supported); } static void Print_DXGI_QUERY_VIDEO_MEMORY_INFO(const DXGI_QUERY_VIDEO_MEMORY_INFO& videoMemoryInfo) { // Not printing videoMemoryInfo.CurrentUsage, videoMemoryInfo.CurrentReservation. - Print_size(L"Budget", videoMemoryInfo.Budget); - Print_size(L"AvailableForReservation", videoMemoryInfo.AvailableForReservation); + ReportFormatter::GetInstance().AddFieldSize(L"Budget", videoMemoryInfo.Budget); + ReportFormatter::GetInstance().AddFieldSize(L"AvailableForReservation", videoMemoryInfo.AvailableForReservation); } static wstring MakeBuildDateTime() @@ -462,74 +466,52 @@ static wstring MakeCurrentDate() return wstring{dateStr}; } -static void PrintHeader_Text() -{ - wprintf(L"============================\n"); - wprintf(L"D3D12INFO %s\n", PROGRAM_VERSION); - wprintf(L"BuildDate: %s\n", MakeBuildDateTime().c_str()); - wprintf(L"Configuration: %s, %s\n", CONFIG_STR, CONFIG_BIT_STR); - wprintf(L"============================\n"); - PrintEmptyLine(); -} - -static void PrintHeader_Json() +static void PrintVersionHeader() { - Json::WriteString(L"Header"); - Json::BeginObject(); - - Json::WriteNameAndString(L"Program", L"D3d12info"); - Json::WriteNameAndString(L"Version", PROGRAM_VERSION); - Json::WriteNameAndString(L"Build Date", MakeBuildDateTime()); - Json::WriteNameAndString(L"Configuration", CONFIG_STR); - Json::WriteNameAndString(L"Configuration bits", CONFIG_BIT_STR); - Json::WriteNameAndString(L"Generated on", MakeCurrentDate().c_str()); #ifdef USE_PREVIEW_AGILITY_SDK - Json::WriteNameAndBool(L"Using preview Agility SDK", true); - Json::WriteNameAndNumber(L"D3D12_PREVIEW_SDK_VERSION", uint32_t(D3D12SDKVersion)); + const wchar_t* const AGILITY_SDK_NOTE = L" (preview Agility SDK)"; #else - Json::WriteNameAndBool(L"Using preview Agility SDK", false); - Json::WriteNameAndNumber(L"D3D12_SDK_VERSION", uint32_t(D3D12SDKVersion)); + const wchar_t* const AGILITY_SDK_NOTE = L""; #endif + Printer::PrintString(L"============================\n"); + Printer::PrintFormat(L"D3D12INFO {}{}\n", std::make_wformat_args(PROGRAM_VERSION, AGILITY_SDK_NOTE)); + Printer::PrintFormat(L"BuildDate: {}\n", std::make_wformat_args(MakeBuildDateTime())); + Printer::PrintFormat(L"Configuration: {}, {}\n", std::make_wformat_args(CONFIG_STR, CONFIG_BIT_STR)); + Printer::PrintString(L"============================"); +} - if(!g_PureD3D12) +static void PrintVersionData() +{ + if (IsOutputConsole()) { -#if USE_NVAPI - NvAPI_Inititalize_RAII::PrintStaticParams(); -#endif -#if USE_AGS - AGS_Initialize_RAII::PrintStaticParams(); -#endif -#if USE_AMD_DEVICE_INFO - AmdDeviceInfo_Initialize_RAII::PrintStaticParams(); -#endif -#if USE_VULKAN - Vulkan_Initialize_RAII::PrintStaticParams(); -#endif -#if USE_INTEL_GPUDETECT - IntelData::PrintStaticParams(); -#endif + PrintVersionHeader(); + Printer::PrintNewLine(); + Printer::PrintNewLine(); } - Json::EndObject(); -} + ReportScopeObject scope(OutputSpecificString(L"General", L"Header")); -static void PrintHeaderData() -{ - if(g_UseJson) - PrintHeader_Json(); - else - PrintHeader_Text(); -} - -static void PrintGeneralData() -{ - PrintHeader(L"General", 0); - ++g_Indent; - Print_string(L"Current date", MakeCurrentDate().c_str()); + if (IsOutputJson()) + { + ReportFormatter::GetInstance().AddFieldString(L"Program", L"D3d12info"); + ReportFormatter::GetInstance().AddFieldString(L"Version", PROGRAM_VERSION); + ReportFormatter::GetInstance().AddFieldString(L"Build Date", MakeBuildDateTime()); + ReportFormatter::GetInstance().AddFieldString(L"Configuration", CONFIG_STR); + ReportFormatter::GetInstance().AddFieldString(L"Configuration bits", CONFIG_BIT_STR); + } + ReportFormatter::GetInstance().AddFieldString(L"Generated on", MakeCurrentDate().c_str()); #ifdef USE_PREVIEW_AGILITY_SDK - Print_uint32(L"D3D12_PREVIEW_SDK_VERSION", uint32_t(D3D12SDKVersion)); + if (IsOutputJson()) + { + ReportFormatter::GetInstance().AddFieldBool(L"Using preview Agility SDK", true); + } + ReportFormatter::GetInstance().AddFieldUint32(L"D3D12_PREVIEW_SDK_VERSION", uint32_t(D3D12SDKVersion)); #else - Print_uint32(L"D3D12_SDK_VERSION", uint32_t(D3D12SDKVersion)); + if (IsOutputJson()) + { + ReportFormatter::GetInstance().AddFieldBool(L"Using preview Agility SDK", false); + } + ReportFormatter::GetInstance().AddFieldUint32(L"D3D12_SDK_VERSION", uint32_t(D3D12SDKVersion)); #endif if(!g_PureD3D12) @@ -550,56 +532,31 @@ static void PrintGeneralData() IntelData::PrintStaticParams(); #endif } - --g_Indent; - PrintEmptyLine(); } -static void PrintEnums_Json() +static void PrintEnums() { - Json::WriteString(L"Enums"); - Json::BeginObject(); + ReportScopeObject scope(L"Enums"); EnumCollection& enumCollection = EnumCollection::GetInstance(); for(const auto it : enumCollection.m_Enums) { - Json::WriteString(it.first.data(), it.first.length()); - Json::BeginObject(); + ReportScopeObject scope2(std::wstring(it.first.data(), it.first.length())); for(const EnumItem* item = it.second; item->m_Name != nullptr; ++item) { - Json::WriteNameAndNumber(item->m_Name, item->m_Value); + ReportFormatter::GetInstance().AddFieldUint32(item->m_Name, item->m_Value); } - - Json::EndObject(); - } - - Json::EndObject(); -} - -static void PrintEnums_Text() -{ - PrintHeader(L"Enums", 0); - PrintEmptyLine(); - - EnumCollection& enumCollection = EnumCollection::GetInstance(); - for(const auto it : enumCollection.m_Enums) - { - PrintHeader(it.first.c_str(), 1); - - for(const EnumItem* item = it.second; item->m_Name != nullptr; ++item) - Print_uint32(item->m_Name, item->m_Value); - - PrintEmptyLine(); } } static void PrintOsVersionInfo() { - ScopedStructRegion region(L"OS Info"); + ReportScopeObject scope(L"OS Info"); HMODULE m = GetModuleHandle(L"ntdll.dll"); if(!m) { - Print_string(L"Windows version", L"Unknown"); + ReportFormatter::GetInstance().AddFieldString(L"Windows version", L"Unknown"); return; } @@ -607,7 +564,7 @@ static void PrintOsVersionInfo() RtlGetVersionFunc RtlGetVersion = (RtlGetVersionFunc)GetProcAddress(m, "RtlGetVersion"); if(!RtlGetVersion) { - Print_string(L"Windows version", L"Unknown"); + ReportFormatter::GetInstance().AddFieldString(L"Windows version", L"Unknown"); return; } @@ -615,14 +572,14 @@ static void PrintOsVersionInfo() // Documentation says it always returns success. RtlGetVersion(&osVersionInfo); - PrintFormat(L"Windows version", L"%lu.%lu.%lu", - osVersionInfo.dwMajorVersion, osVersionInfo.dwMinorVersion, - osVersionInfo.dwBuildNumber); + ReportFormatter::GetInstance().AddFieldString(L"Windows version", std::format(L"{}.{}.{}", + osVersionInfo.dwMajorVersion, osVersionInfo.dwMinorVersion, + osVersionInfo.dwBuildNumber)); } static void PrintDXGIFeatureInfo() { - ScopedStructRegion region(L"DXGI_FEATURE"); + ReportScopeObject scope(L"DXGI_FEATURE"); ComPtr dxgiFactory = nullptr; HRESULT hr; #if defined(AUTO_LINK_DX12) @@ -637,24 +594,24 @@ static void PrintDXGIFeatureInfo() &allowTearing, sizeof(allowTearing)); if(SUCCEEDED(hr)) { - Print_BOOL(L"DXGI_FEATURE_PRESENT_ALLOW_TEARING", allowTearing); + ReportFormatter::GetInstance().AddFieldBool(L"DXGI_FEATURE_PRESENT_ALLOW_TEARING", allowTearing); } } static void PrintSystemMemoryInfo() { - ScopedStructRegion region(L"System memory"); + ReportScopeObject scope(L"System memory"); if(uint64_t physicallyInstalledSystemMemory = 0; GetPhysicallyInstalledSystemMemory(&physicallyInstalledSystemMemory)) - Print_sizeKilobytes(L"GetPhysicallyInstalledSystemMemory", physicallyInstalledSystemMemory); + ReportFormatter::GetInstance().AddFieldSizeKilobytes(L"GetPhysicallyInstalledSystemMemory", physicallyInstalledSystemMemory); if(MEMORYSTATUSEX memStatEx = {sizeof(MEMORYSTATUSEX)}; GlobalMemoryStatusEx(&memStatEx)) { - Print_size(L"MEMORYSTATUSEX::ullTotalPhys", memStatEx.ullTotalPhys); - Print_size(L"MEMORYSTATUSEX::ullTotalPageFile", memStatEx.ullTotalPageFile); - Print_size(L"MEMORYSTATUSEX::ullTotalVirtual", memStatEx.ullTotalVirtual); + ReportFormatter::GetInstance().AddFieldSize(L"MEMORYSTATUSEX::ullTotalPhys", memStatEx.ullTotalPhys); + ReportFormatter::GetInstance().AddFieldSize(L"MEMORYSTATUSEX::ullTotalPageFile", memStatEx.ullTotalPageFile); + ReportFormatter::GetInstance().AddFieldSize(L"MEMORYSTATUSEX::ullTotalVirtual", memStatEx.ullTotalVirtual); } } @@ -703,92 +660,69 @@ static void EnableExperimentalFeatures() if(featureBitMask != 0) // Means enablement succeeded. { - if(g_UseJson) - { - Json::WriteString(L"D3D12EnableExperimentalFeatures"); - Json::BeginArray(); - for(size_t featureIndex = 0; featureIndex < FEATURE_COUNT; ++featureIndex) - { - if((featureBitMask & (1u << featureIndex)) != 0) - Json::WriteString(FEATURE_NAMES[featureIndex]); - } - Json::EndArray(); - } - else - { - PrintHeader(L"D3D12EnableExperimentalFeatures", 1); - ++g_Indent; + std::vector enabledFeatures; - for(size_t featureIndex = 0; featureIndex < FEATURE_COUNT; ++featureIndex) + for(size_t featureIndex = 0; featureIndex < FEATURE_COUNT; ++featureIndex) + { + if((featureBitMask & (1u << featureIndex)) != 0) { - if((featureBitMask & (1u << featureIndex)) != 0) - { - PrintIndent(); - wprintf(L"%s\n", FEATURE_NAMES[featureIndex]); - } + enabledFeatures.push_back(FEATURE_NAMES[featureIndex]); } - - --g_Indent; - PrintEmptyLine(); } - } -} -static void PrintEnumsData() -{ - if(g_UseJson) - PrintEnums_Json(); - else - PrintEnums_Text(); + std::wstring enabledFeaturesStr = std::accumulate(enabledFeatures.begin(), enabledFeatures.end(), std::wstring{}, + [](const std::wstring& a, const std::wstring& b) { return a.empty() ? b : a + L"," + b; }); + ReportFormatter::GetInstance().AddFieldString(L"D3D12EnableExperimentalFeatures", enabledFeaturesStr); + } } static void PrintAdapterDescMembers(const DXGI_ADAPTER_DESC& desc) { - Print_string(L"Description", desc.Description); - PrintVendorId(L"VendorId", desc.VendorId); - Print_hex32(L"DeviceId", desc.DeviceId); - PrintSubsystemId(L"SubSysId", desc.SubSysId); - Print_hex32(L"Revision", desc.Revision); - Print_size(L"DedicatedVideoMemory", desc.DedicatedVideoMemory); - Print_size(L"DedicatedSystemMemory", desc.DedicatedSystemMemory); - Print_size(L"SharedSystemMemory", desc.SharedSystemMemory); - Print_string(L"AdapterLuid", LuidToStr(desc.AdapterLuid).c_str()); + ReportFormatter::GetInstance().AddFieldString(L"Description", desc.Description); + ReportFormatter::GetInstance().AddFieldVendorId(L"VendorId", desc.VendorId); + ReportFormatter::GetInstance().AddFieldHex32(L"DeviceId", desc.DeviceId); + ReportFormatter::GetInstance().AddFieldSubsystemId(L"SubSysId", desc.SubSysId); + ReportFormatter::GetInstance().AddFieldHex32(L"Revision", desc.Revision); + ReportFormatter::GetInstance().AddFieldSize(L"DedicatedVideoMemory", desc.DedicatedVideoMemory); + ReportFormatter::GetInstance().AddFieldSize(L"DedicatedSystemMemory", desc.DedicatedSystemMemory); + ReportFormatter::GetInstance().AddFieldSize(L"SharedSystemMemory", desc.SharedSystemMemory); + ReportFormatter::GetInstance().AddFieldString(L"AdapterLuid", LuidToStr(desc.AdapterLuid).c_str()); } static void PrintAdapterDesc1Members(const DXGI_ADAPTER_DESC1& desc1) { PrintAdapterDescMembers((const DXGI_ADAPTER_DESC&)desc1); - PrintFlags(L"Flags", desc1.Flags, Enum_DXGI_ADAPTER_FLAG); + ReportFormatter::GetInstance().AddFieldFlags(L"Flags", desc1.Flags, Enum_DXGI_ADAPTER_FLAG); } static void PrintAdapterDesc2Members(const DXGI_ADAPTER_DESC2& desc2) { PrintAdapterDesc1Members((const DXGI_ADAPTER_DESC1&)desc2); - PrintEnum(L"GraphicsPreemptionGranularity", desc2.GraphicsPreemptionGranularity, Enum_DXGI_GRAPHICS_PREEMPTION_GRANULARITY); - PrintEnum(L"ComputePreemptionGranularity", desc2.ComputePreemptionGranularity, Enum_DXGI_COMPUTE_PREEMPTION_GRANULARITY); + ReportFormatter::GetInstance().AddFieldEnum(L"GraphicsPreemptionGranularity", desc2.GraphicsPreemptionGranularity, Enum_DXGI_GRAPHICS_PREEMPTION_GRANULARITY); + ReportFormatter::GetInstance().AddFieldEnum(L"ComputePreemptionGranularity", desc2.ComputePreemptionGranularity, Enum_DXGI_COMPUTE_PREEMPTION_GRANULARITY); } static void PrintAdapterDesc(const DXGI_ADAPTER_DESC& desc) { - ScopedStructRegion region(L"DXGI_ADAPTER_DESC"); + ReportScopeObject scope(L"DXGI_ADAPTER_DESC"); PrintAdapterDescMembers(desc); } static void PrintAdapterDesc1(const DXGI_ADAPTER_DESC1& desc1) { - ScopedStructRegion region(L"DXGI_ADAPTER_DESC1"); + ReportScopeObject scope(L"DXGI_ADAPTER_DESC1"); PrintAdapterDesc1Members(desc1); } static void PrintAdapterDesc2(const DXGI_ADAPTER_DESC2& desc2) { - ScopedStructRegion region(L"DXGI_ADAPTER_DESC2"); + ReportScopeObject scope(L"DXGI_ADAPTER_DESC2"); PrintAdapterDesc2Members(desc2); } static void PrintAdapterDesc3(const DXGI_ADAPTER_DESC3& desc3) { - ScopedStructRegion region(L"DXGI_ADAPTER_DESC3"); + ReportScopeObject scope(L"DXGI_ADAPTER_DESC3"); // Same members as DESC2. They only added new items to Flags. PrintAdapterDesc2Members((const DXGI_ADAPTER_DESC2&)desc3); } @@ -839,7 +773,7 @@ static void PrintAdapterMemoryInfo(IDXGIAdapter* adapter) assert(0); } { - ScopedStructRegion region(structName); + ReportScopeObject scope(structName); Print_DXGI_QUERY_VIDEO_MEMORY_INFO(videoMemoryInfo); } } @@ -851,20 +785,8 @@ static void PrintAdapterInterfaceSupport(IDXGIAdapter* adapter) { if(LARGE_INTEGER i; SUCCEEDED(adapter->CheckInterfaceSupport(__uuidof(IDXGIDevice), &i))) { - ScopedStructRegion region(L"CheckInterfaceSupport"); - if(g_UseJson) - { - Print_uint64(L"UMDVersion", i.QuadPart); - } - else - { - wstring s = std::format(L"{}.{}.{}.{}", - i.QuadPart >> 48, - (i.QuadPart >> 32) & 0xFFFF, - (i.QuadPart >> 16) & 0xFFFF, - i.QuadPart & 0xFFFF); - Print_string(L"UMDVersion", s.c_str()); - } + ReportScopeObject scope(L"CheckInterfaceSupport"); + ReportFormatter::GetInstance().AddFieldMicrosoftVersion(L"UMDVersion", i.QuadPart); } } @@ -895,13 +817,7 @@ static FormatSupportResult CheckFormatSupport(ID3D12Device* device, D3D12_FEATUR static void PrintFormatInformation(ID3D12Device* device) { - if(g_UseJson) - { - Json::WriteString(L"Formats"); - Json::BeginObject(); - } - else - PrintHeader(L"Formats", 1); + ReportScopeObject scope(L"Formats"); D3D12_FEATURE_DATA_FORMAT_SUPPORT formatSupport = {}; D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS msQualityLevels = {}; @@ -916,85 +832,49 @@ static void PrintFormatInformation(ID3D12Device* device) const FormatSupportResult formatSupportResult = CheckFormatSupport(device, formatSupport); if(formatSupportResult == FormatSupportResult::Crashed) { - fwprintf(stderr, L"ERROR: ID3D12Device::CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, %s) crashed.\n", - name); + ErrorPrinter::PrintFormat(L"ERROR: ID3D12Device::CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, {}) crashed.\n", std::make_wformat_args(name)); break; } - if(g_UseJson) - { - Json::WriteString(std::format(L"{}", (size_t)format)); - Json::BeginObject(); - } - else - { - PrintIndent(); - wprintf(L"%s:\n", name); - ++g_Indent; - } + ReportScopeObjectConditional scope2(OutputSpecificString(name, std::format(L"{}", (size_t)format))); if(formatSupportResult == FormatSupportResult::Ok) { - PrintFlags(L"Support1", formatSupport.Support1, Enum_D3D12_FORMAT_SUPPORT1); - PrintFlags(L"Support2", formatSupport.Support2, Enum_D3D12_FORMAT_SUPPORT2); - - if(g_UseJson) - { - Json::WriteString(L"MultisampleQualityLevels"); - Json::BeginObject(); - } + scope2.Enable(); + ReportFormatter::GetInstance().AddFieldFlags(L"Support1", formatSupport.Support1, Enum_D3D12_FORMAT_SUPPORT1); + ReportFormatter::GetInstance().AddFieldFlags(L"Support2", formatSupport.Support2, Enum_D3D12_FORMAT_SUPPORT2); + + ReportScopeObjectConditional scope3(IsOutputJson(), L"MultisampleQualityLevels"); msQualityLevels.Format = format; for(msQualityLevels.SampleCount = 1; ; msQualityLevels.SampleCount *= 2) { if(SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &msQualityLevels, UINT(sizeof msQualityLevels))) && msQualityLevels.NumQualityLevels > 0) { - if(g_UseJson) + if(IsOutputJson()) { - Json::WriteString(std::format(L"{}", msQualityLevels.SampleCount)); - Json::BeginObject(); - - Json::WriteNameAndNumber(L"NumQualityLevels", msQualityLevels.NumQualityLevels); - Json::WriteNameAndNumber(L"Flags", uint32_t(msQualityLevels.Flags)); - - Json::EndObject(); + ReportScopeObject scope4(std::format(L"{}", msQualityLevels.SampleCount)); + ReportFormatter::GetInstance().AddFieldUint32(L"NumQualityLevels", msQualityLevels.NumQualityLevels); + ReportFormatter::GetInstance().AddFieldUint32(L"Flags", uint32_t(msQualityLevels.Flags)); } else { - PrintIndent(); - wprintf(L"SampleCount = %u: NumQualityLevels = %u", msQualityLevels.SampleCount, msQualityLevels.NumQualityLevels); - if((msQualityLevels.Flags & D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_TILED_RESOURCE) != 0) - wprintf(L" D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_TILED_RESOURCE\n"); - else - wprintf(L"\n"); + bool multisampleTiled = (msQualityLevels.Flags & D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_TILED_RESOURCE) != 0; + ReportFormatter::GetInstance().AddFieldString(L"SampleCount", std::format(L"{}: NumQualityLevels = {}{}", msQualityLevels.SampleCount, msQualityLevels.NumQualityLevels, multisampleTiled ? L" D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_TILED_RESOURCE" : L"")); } } else break; } - if(g_UseJson) - Json::EndObject(); } formatInfo.Format = format; if(SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &formatInfo, UINT(sizeof formatInfo)))) { - Print_uint32(L"PlaneCount", formatInfo.PlaneCount); - } - - if(g_UseJson) - Json::EndObject(); - else - { - --g_Indent; - PrintEmptyLine(); + scope2.Enable(); + ReportFormatter::GetInstance().AddFieldUint32(L"PlaneCount", formatInfo.PlaneCount); } } - - if(g_UseJson) - Json::EndObject(); - else - PrintEmptyLine(); } static void PrintDeviceOptions(ID3D12Device* device) @@ -1100,34 +980,25 @@ static void PrintDeviceOptions(ID3D12Device* device) static void PrintDescriptorSizes(ID3D12Device* device) { - ScopedStructRegion region(L"GetDescriptorHandleIncrementSize"); - Print_uint32(L"D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV", + ReportScopeObject scope(L"GetDescriptorHandleIncrementSize"); + ReportFormatter::GetInstance().AddFieldUint32(L"D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV", device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)); - Print_uint32(L"D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER", + ReportFormatter::GetInstance().AddFieldUint32(L"D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER", device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER)); - Print_uint32(L"D3D12_DESCRIPTOR_HEAP_TYPE_RTV", + ReportFormatter::GetInstance().AddFieldUint32(L"D3D12_DESCRIPTOR_HEAP_TYPE_RTV", device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV)); - Print_uint32(L"D3D12_DESCRIPTOR_HEAP_TYPE_DSV", + ReportFormatter::GetInstance().AddFieldUint32(L"D3D12_DESCRIPTOR_HEAP_TYPE_DSV", device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV)); } static void PrintMetaCommand(ID3D12Device5* device5, UINT index, const D3D12_META_COMMAND_DESC& desc) { - if(g_UseJson) - { - Json::BeginObject(); - } - else - { - PrintIndent(); - wprintf(L"MetaCommand %u:\n", index); - ++g_Indent; - } + ReportScopeArrayItem scope; - Print_string(L"Id", GuidToStr(desc.Id).c_str()); - Print_string(L"Name", desc.Name); - PrintFlags(L"InitializationDirtyState", desc.InitializationDirtyState, Enum_D3D12_GRAPHICS_STATES); - PrintFlags(L"ExecutionDirtyState", desc.ExecutionDirtyState, Enum_D3D12_GRAPHICS_STATES); + ReportFormatter::GetInstance().AddFieldString(L"Id", GuidToStr(desc.Id).c_str()); + ReportFormatter::GetInstance().AddFieldString(L"Name", desc.Name); + ReportFormatter::GetInstance().AddFieldFlags(L"InitializationDirtyState", desc.InitializationDirtyState, Enum_D3D12_GRAPHICS_STATES); + ReportFormatter::GetInstance().AddFieldFlags(L"ExecutionDirtyState", desc.ExecutionDirtyState, Enum_D3D12_GRAPHICS_STATES); for(UINT stageIndex = 0; stageIndex < 3; ++stageIndex) { @@ -1138,22 +1009,12 @@ static void PrintMetaCommand(ID3D12Device5* device5, UINT index, const D3D12_MET &totalStructureSizeInBytes, ¶mCount, nullptr); if(FAILED(hr)) continue; - - if(g_UseJson) - { - Json::WriteString(Enum_D3D12_META_COMMAND_PARAMETER_STAGE[stageIndex].m_Name); - Json::BeginObject(); - Print_uint32(L"TotalStructureSizeInBytes", totalStructureSizeInBytes); - } - else + { - PrintIndent(); - wprintf(L"%s: TotalStructureSizeInBytes=%u\n", - Enum_D3D12_META_COMMAND_PARAMETER_STAGE[stageIndex].m_Name, - totalStructureSizeInBytes); - ++g_Indent; + ReportScopeObject scope2(Enum_D3D12_META_COMMAND_PARAMETER_STAGE[stageIndex].m_Name); + ReportFormatter::GetInstance().AddFieldUint32(L"TotalStructureSizeInBytes", totalStructureSizeInBytes); } - + if(paramCount > 0) { std::vector paramDescs(paramCount); @@ -1162,54 +1023,22 @@ static void PrintMetaCommand(ID3D12Device5* device5, UINT index, const D3D12_MET nullptr, ¶mCount, paramDescs.data()); if(SUCCEEDED(hr)) { - if(g_UseJson) - { - Json::WriteString(L"Parameters"); - Json::BeginArray(); - } + ReportScopeArray scope2(L"Parameters"); for(UINT paramIndex = 0; paramIndex < paramCount; ++paramIndex) { const auto& paramDesc = paramDescs[paramIndex]; - if(g_UseJson) - Json::BeginObject(); - else - { - PrintIndent(); - wprintf(L"Parameter %u:\n", paramIndex); - ++g_Indent; - } - - Print_string(L"Name", paramDesc.Name); - PrintEnum(L"Type", paramDesc.Type, Enum_D3D12_META_COMMAND_PARAMETER_TYPE); - PrintFlags(L"Flags", paramDesc.Flags, Enum_D3D12_META_COMMAND_PARAMETER_FLAGS); - PrintFlags(L"RequiredResourceState", paramDesc.RequiredResourceState, Enum_D3D12_RESOURCE_STATES); - Print_uint32(L"StructureOffset", paramDesc.StructureOffset); + ReportScopeArrayItem scope3; - if(g_UseJson) - Json::EndObject(); - else - --g_Indent; + ReportFormatter::GetInstance().AddFieldString(L"Name", paramDesc.Name); + ReportFormatter::GetInstance().AddFieldEnum(L"Type", paramDesc.Type, Enum_D3D12_META_COMMAND_PARAMETER_TYPE); + ReportFormatter::GetInstance().AddFieldFlags(L"Flags", paramDesc.Flags, Enum_D3D12_META_COMMAND_PARAMETER_FLAGS); + ReportFormatter::GetInstance().AddFieldFlags(L"RequiredResourceState", paramDesc.RequiredResourceState, Enum_D3D12_RESOURCE_STATES); + ReportFormatter::GetInstance().AddFieldUint32(L"StructureOffset", paramDesc.StructureOffset); } - - if(g_UseJson) - Json::EndArray(); } } - - if(g_UseJson) - Json::EndObject(); - else - --g_Indent; - } - - if(g_UseJson) - Json::EndObject(); - else - { - --g_Indent; - PrintEmptyLine(); } } @@ -1223,25 +1052,11 @@ static void PrintMetaCommands(ID3D12Device5* device5) std::vector descs(num); if(FAILED(device5->EnumerateMetaCommands(&num, descs.data()))) return; - - if(g_UseJson) - { - Json::WriteString(L"EnumerateMetaCommands"); - Json::BeginArray(); - } - else - { - PrintHeader(L"EnumerateMetaCommands", 1); - ++g_Indent; - } + + ReportScopeArray scope(L"EnumerateMetaCommands"); for(UINT i = 0; i < num; ++i) PrintMetaCommand(device5, i, descs[i]); - - if(g_UseJson) - Json::EndArray(); - else - --g_Indent; } static void PrintCommandQueuePriorities(ID3D12Device* device) @@ -1281,28 +1096,14 @@ static void PrintCommandQueuePriorities(ID3D12Device* device) static void PrintDirectSROptimizationRankings(const DSR_OPTIMIZATION_TYPE* optimizationRankings) { constexpr size_t count = _countof(DSR_SUPERRES_VARIANT_DESC::OptimizationRankings); - if(g_UseJson) - { - Json::WriteString(L"OptimizationRankings"); - Json::BeginArray(); - ++g_Indent; - for(size_t i = 0; i < count; ++i) - Json::WriteNumber((uint32_t)optimizationRankings[i]); - Json::EndArray(); - } - else + + uint32_t rankingsCopy[count]; + for(size_t i = 0; i < count; ++i) { - PrintIndent(); - wprintf(L"OptimizationRankings:\n"); - ++g_Indent; - for(size_t i = 0; i < count; ++i) - { - const DSR_OPTIMIZATION_TYPE optimizationType = optimizationRankings[i]; - PrintIndent(); - wprintf(L"%s\n", Enum_DSR_OPTIMIZATION_TYPE[optimizationType].m_Name); - } - --g_Indent; + rankingsCopy[i] = (uint32_t)optimizationRankings[i]; } + + ReportFormatter::GetInstance().AddEnumArray(L"OptimizationRankings", rankingsCopy, count, Enum_DSR_OPTIMIZATION_TYPE); } static void PrintDirectSR(ID3D12Device* device) @@ -1317,51 +1118,22 @@ static void PrintDirectSR(ID3D12Device* device) if(numVariants == 0) return; - if(g_UseJson) - { - Json::WriteString(L"DirectSR"); - Json::BeginArray(); - } - else - { - PrintHeader(L"DirectSR", 1); - ++g_Indent; - } + ReportScopeArray scope(L"DirectSR"); for(UINT variantIndex = 0; variantIndex < numVariants; ++variantIndex) { DSR_SUPERRES_VARIANT_DESC desc = {}; if(SUCCEEDED(dsrDevice->GetSuperResVariantDesc(variantIndex, &desc))) { - if(g_UseJson) - Json::BeginObject(); - else - { - PrintIndent(); - wprintf(L"Variant %u:\n", variantIndex); - ++g_Indent; - } - - Print_string(L"VariantId", GuidToStr(desc.VariantId).c_str()); - Print_string(L"VariantName", StrToWstr(desc.VariantName, CP_UTF8).c_str()); - PrintFlags(L"Flags", desc.Flags, Enum_DSR_SUPERRES_VARIANT_FLAGS); - PrintDirectSROptimizationRankings(desc.OptimizationRankings); - PrintEnum(L"OptimalTargetFormat", desc.OptimalTargetFormat, Enum_DXGI_FORMAT); + ReportScopeArrayItem scope2; - if(g_UseJson) - Json::EndObject(); - else - { - --g_Indent; - PrintEmptyLine(); - } + ReportFormatter::GetInstance().AddFieldString(L"VariantId", GuidToStr(desc.VariantId).c_str()); + ReportFormatter::GetInstance().AddFieldString(L"VariantName", StrToWstr(desc.VariantName, CP_UTF8).c_str()); + ReportFormatter::GetInstance().AddFieldFlags(L"Flags", desc.Flags, Enum_DSR_SUPERRES_VARIANT_FLAGS); + PrintDirectSROptimizationRankings(desc.OptimizationRankings); + ReportFormatter::GetInstance().AddFieldEnum(L"OptimalTargetFormat", desc.OptimalTargetFormat, Enum_DXGI_FORMAT); } } - - if(g_UseJson) - Json::EndArray(); - else - --g_Indent; } #endif // #ifdef USE_PREVIEW_AGILITY_SDK @@ -1528,14 +1300,14 @@ static bool LoadLibraries() g_DxgiLibrary = ::LoadLibraryEx(DYN_LIB_DXGI, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); if (!g_DxgiLibrary) { - wprintf(L"could not load %s\n", DYN_LIB_DXGI); + ErrorPrinter::PrintFormat(L"could not load {}\n", std::make_wformat_args(DYN_LIB_DXGI)); return false; } g_Dx12Library = ::LoadLibraryEx(DYN_LIB_DX12, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); if (!g_Dx12Library) { - wprintf(L"could not load %s\n", DYN_LIB_DX12); + ErrorPrinter::PrintFormat(L"could not load {}\n", std::make_wformat_args(DYN_LIB_DX12)); return false; } @@ -1581,42 +1353,44 @@ static void UnloadLibraries() #endif -static void PrintCommandLineSyntax() -{ - wprintf(L"Options:\n"); - wprintf(L" -v --Version Only print program version information.\n"); - wprintf(L" -h --Help Only print this help (command line syntax).\n"); - wprintf(L" -l --List Only print the list of all adapters.\n"); - wprintf(L" -a --Adapter= Print details of adapter at specified index.\n"); - wprintf(L" --AllNonSoftware Print details of all (except WARP and Software) adapters (default behavior).\n"); - wprintf(L" --AllAdapters Print details of all (except WARP) adapters.\n"); - wprintf(L" -j --JSON Print output in JSON format instead of human-friendly text.\n"); - wprintf(L" -f --Formats Include information about DXGI format capabilities.\n"); - wprintf(L" --MetaCommands Include information about meta commands.\n"); - wprintf(L" -e --Enums Include information about all known enums and their values.\n"); - wprintf(L" --PureD3D12 Extract information only from D3D12 and no other sources.\n"); +template +void PrintCommandLineSyntax() +{ + PrinterClass::PrintString(L"Options:\n"); + PrinterClass::PrintString(L" -v --Version Only print program version information.\n"); + PrinterClass::PrintString(L" -h --Help Only print this help (command line syntax).\n"); + PrinterClass::PrintString(L" -l --List Only print the list of all adapters.\n"); + PrinterClass::PrintString(L" -a --Adapter= Print details of adapter at specified index.\n"); + PrinterClass::PrintString(L" --AllNonSoftware Print details of all (except Software) adapters (default behavior).\n"); + PrinterClass::PrintString(L" --AllAdapters Print details of all adapters.\n"); + PrinterClass::PrintString(L" -j --JSON Print output in JSON format instead of human-friendly text.\n"); + PrinterClass::PrintString(L" --JSONPrettyPrint Print JSON in human friendly form. (default behavior)\n"); + PrinterClass::PrintString(L" --JSONNoPrettyPrint Print JSON in minimal size form.\n"); + PrinterClass::PrintString(L" -o --OutputToFile= Output to specified file.\n"); + PrinterClass::PrintString(L" -f --Formats Include information about DXGI format capabilities.\n"); + PrinterClass::PrintString(L" --MetaCommands Include information about meta commands.\n"); + PrinterClass::PrintString(L" -e --Enums Include information about all known enums and their values.\n"); + PrinterClass::PrintString(L" --PureD3D12 Extract information only from D3D12 and no other sources.\n"); #ifdef USE_PREVIEW_AGILITY_SDK - wprintf(L" -x --EnableExperimental= Whether to enable experimental features before querying device capabilities. Default is on (off for D3d12info and on for D3d12info_preview).\n"); + PrinterClass::PrintString(L" -x --EnableExperimental= Whether to enable experimental features before querying device capabilities. Default is on (off for D3d12info and on for D3d12info_preview).\n"); #else - wprintf(L" -x --EnableExperimental= Whether to enable experimental features before querying device capabilities. Default is off (off for D3d12info and on for D3d12info_preview).\n"); + PrinterClass::PrintString(L" -x --EnableExperimental= Whether to enable experimental features before querying device capabilities. Default is off (off for D3d12info and on for D3d12info_preview).\n"); #endif - wprintf(L" --ForceVendorAPI Tries to query info via vendor-specific APIs, even in case when vendor doesn't match.\n"); - wprintf(L" --WARP Use WARP adapter.\n"); + PrinterClass::PrintString(L" --ForceVendorAPI Tries to query info via vendor-specific APIs, even in case when vendor doesn't match.\n"); + PrinterClass::PrintString(L" --WARP Use WARP adapter.\n"); } static void ListAdapter(uint32_t adapterIndex, IDXGIAdapter* adapter, NvAPI_Inititalize_RAII* nvApi, AGS_Initialize_RAII* ags, AmdDeviceInfo_Initialize_RAII* amdDeviceInfo, Vulkan_Initialize_RAII* vk) { - if(g_UseJson) - { - Json::BeginObject(); - Print_uint32(L"AdapterIndex", adapterIndex); - } - else + ReportScopeArrayItem scope; + + if(!g_WARP && !g_ShowAllAdapters) { - PrintHeader(std::format(L"DXGI Adapter {}", adapterIndex).c_str(), 0); - PrintEmptyLine(); + // In case of WARP, we queried adapter via different API that didn't use adapter index + // In case we show all adapters, array index equals adapter index + ReportFormatter::GetInstance().AddFieldUint32(L"AdapterIndex", adapterIndex); } PrintAdapterData(adapter); @@ -1655,9 +1429,6 @@ static void ListAdapter(uint32_t adapterIndex, IDXGIAdapter* adapter, vk->PrintData(desc); #endif } - - if(g_UseJson) - Json::EndObject(); } static void ListAdapters(IDXGIFactory4* dxgiFactory, NvAPI_Inititalize_RAII* nvApi, AGS_Initialize_RAII* ags, @@ -1685,17 +1456,15 @@ int InspectAdapter(NvAPI_Inititalize_RAII* nvApi, AGS_Initialize_RAII* ags, AmdDeviceInfo_Initialize_RAII* amdDeviceInfo, Vulkan_Initialize_RAII* vk, uint32_t& adapterIndex, ComPtr& adapter1) { + ReportScopeArrayItemConditional scope(g_PrintAdaptersAsArray); + int programResult = PROGRAM_EXIT_SUCCESS; - if(g_UseJson) + if(!g_WARP && !g_ShowAllAdapters) { - Json::BeginObject(); - Print_uint32(L"AdapterIndex", adapterIndex); - } - else - { - PrintHeader(std::format(L"DXGI Adapter {}", adapterIndex).c_str(), 0); - PrintEmptyLine(); + // In case of WARP, we queried adapter via different API that didn't use adapter index + // In case we show all adapters, array index equals adapter index + ReportFormatter::GetInstance().AddFieldUint32(L"AdapterIndex", adapterIndex); } PrintAdapterData(adapter1.Get()); @@ -1746,9 +1515,6 @@ int InspectAdapter(NvAPI_Inititalize_RAII* nvApi, AGS_Initialize_RAII* ags, programResult = PrintDeviceDetails(adapter1.Get(), nvApi, ags); - if(g_UseJson) - Json::EndObject(); - return programResult; } @@ -1833,6 +1599,9 @@ int wmain3(int argc, wchar_t** argv) CMD_LINE_OPT_ALL_NON_SOFTWARE, CMD_LINE_OPT_ALL_ADAPTERS, CMD_LINE_OPT_JSON, + CMD_LINE_OPT_JSON_PRETTY_PRINT, + CMD_LINE_OPT_JSON_NO_PRETTY_PRINT, + CMD_LINE_OPT_OUTPUT_TO_FILE, CMD_LINE_OPT_FORMATS, CMD_LINE_OPT_META_COMMANDS, CMD_LINE_OPT_ENUMS, @@ -1854,6 +1623,10 @@ int wmain3(int argc, wchar_t** argv) cmdLineParser.RegisterOpt(CMD_LINE_OPT_ALL_ADAPTERS, L"AllAdapters", false); cmdLineParser.RegisterOpt(CMD_LINE_OPT_JSON, L"JSON", false); cmdLineParser.RegisterOpt(CMD_LINE_OPT_JSON, L'j', false); + cmdLineParser.RegisterOpt(CMD_LINE_OPT_JSON_PRETTY_PRINT, L"JSONPrettyPrint", false); + cmdLineParser.RegisterOpt(CMD_LINE_OPT_JSON_NO_PRETTY_PRINT, L"JSONNoPrettyPrint", false); + cmdLineParser.RegisterOpt(CMD_LINE_OPT_OUTPUT_TO_FILE, L'o', true); + cmdLineParser.RegisterOpt(CMD_LINE_OPT_OUTPUT_TO_FILE, L"OutputToFile", true); cmdLineParser.RegisterOpt(CMD_LINE_OPT_FORMATS, L"Formats", false); cmdLineParser.RegisterOpt(CMD_LINE_OPT_FORMATS, L'f', false); cmdLineParser.RegisterOpt(CMD_LINE_OPT_META_COMMANDS, L"MetaCommands", false); @@ -1872,25 +1645,25 @@ int wmain3(int argc, wchar_t** argv) { case CmdLineParser::RESULT_ERROR: case CmdLineParser::RESULT_PARAMETER: - PrintCommandLineSyntax(); - return PROGRAM_EXIT_ERROR_COMMAND_LINE; + g_ShowCommandLineSyntaxAndFail = true; + break; case CmdLineParser::RESULT_OPT: switch(cmdLineParser.GetOptId()) { case CMD_LINE_OPT_VERSION: - PrintHeader_Text(); - return PROGRAM_EXIT_SUCCESS; + g_ShowVersionAndQuit = true; + break; case CMD_LINE_OPT_HELP: - PrintCommandLineSyntax(); - return PROGRAM_EXIT_SUCCESS; + g_ShowCommandLineSyntaxAndQuit = true; + break; case CMD_LINE_OPT_LIST: if(cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ADAPTER) || cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ALL_NON_SOFTWARE) || cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ALL_ADAPTERS) || cmdLineParser.IsOptEncountered(CMD_LINE_OPT_WARP)) { - PrintCommandLineSyntax(); - return PROGRAM_EXIT_ERROR_COMMAND_LINE; + g_ShowCommandLineSyntaxAndFail = true; + break; } g_ListAdapters = true; break; @@ -1900,8 +1673,8 @@ int wmain3(int argc, wchar_t** argv) cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ALL_ADAPTERS) || cmdLineParser.IsOptEncountered(CMD_LINE_OPT_WARP)) { - PrintCommandLineSyntax(); - return PROGRAM_EXIT_ERROR_COMMAND_LINE; + g_ShowCommandLineSyntaxAndFail = true; + break; } g_ShowAllAdapters = false; adapterIndex = _wtoi(cmdLineParser.GetParameter().c_str()); @@ -1912,8 +1685,8 @@ int wmain3(int argc, wchar_t** argv) cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ALL_ADAPTERS) || cmdLineParser.IsOptEncountered(CMD_LINE_OPT_WARP)) { - PrintCommandLineSyntax(); - return PROGRAM_EXIT_ERROR_COMMAND_LINE; + g_ShowCommandLineSyntaxAndFail = true; + break; } g_ShowAllAdapters = true; g_SkipSoftwareAdapter = true; @@ -1925,15 +1698,25 @@ int wmain3(int argc, wchar_t** argv) cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ALL_NON_SOFTWARE) || cmdLineParser.IsOptEncountered(CMD_LINE_OPT_WARP)) { - PrintCommandLineSyntax(); - return PROGRAM_EXIT_ERROR_COMMAND_LINE; + g_ShowCommandLineSyntaxAndFail = true; + break; } g_ShowAllAdapters = true; g_SkipSoftwareAdapter = false; adapterIndex = UINT32_MAX; break; case CMD_LINE_OPT_JSON: - g_UseJson = true; + g_UseJsonOutput = true; + break; + case CMD_LINE_OPT_JSON_PRETTY_PRINT: + g_UseJsonPrettyPrint = true; + break; + case CMD_LINE_OPT_JSON_NO_PRETTY_PRINT: + g_UseJsonPrettyPrint = false; + break; + case CMD_LINE_OPT_OUTPUT_TO_FILE: + g_OutputToFile = true; + g_OutputFilePath = cmdLineParser.GetParameter(); break; case CMD_LINE_OPT_FORMATS: g_PrintFormats = true; @@ -1947,8 +1730,8 @@ int wmain3(int argc, wchar_t** argv) case CMD_LINE_OPT_PURE_D3D12: if (cmdLineParser.IsOptEncountered(CMD_LINE_OPT_FORCE_VENDOR_SPECIFIC)) { - PrintCommandLineSyntax(); - return PROGRAM_EXIT_ERROR_COMMAND_LINE; + g_ShowCommandLineSyntaxAndFail = true; + break; } g_PureD3D12 = true; break; @@ -1959,8 +1742,8 @@ int wmain3(int argc, wchar_t** argv) bool isOff = ::_wcsicmp(param.c_str(), L"off") == 0; if (!isOn && !isOff) { - PrintCommandLineSyntax(); - return PROGRAM_EXIT_ERROR_COMMAND_LINE; + g_ShowCommandLineSyntaxAndFail = true; + break; } g_EnableExperimental = isOn; } @@ -1968,8 +1751,8 @@ int wmain3(int argc, wchar_t** argv) case CMD_LINE_OPT_FORCE_VENDOR_SPECIFIC: if (cmdLineParser.IsOptEncountered(CMD_LINE_OPT_PURE_D3D12)) { - PrintCommandLineSyntax(); - return PROGRAM_EXIT_ERROR_COMMAND_LINE; + g_ShowCommandLineSyntaxAndFail = true; + break; } g_ForceVendorAPI = true; break; @@ -1979,25 +1762,87 @@ int wmain3(int argc, wchar_t** argv) cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ALL_NON_SOFTWARE) || cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ALL_ADAPTERS)) { - PrintCommandLineSyntax(); - return PROGRAM_EXIT_ERROR_COMMAND_LINE; + g_ShowCommandLineSyntaxAndFail = true; + break; } g_WARP = true; break; default: - PrintCommandLineSyntax(); - return PROGRAM_EXIT_ERROR_COMMAND_LINE; + g_ShowCommandLineSyntaxAndFail = true; + break; } break; default: assert(0); + g_ShowCommandLineSyntaxAndFail = true; + break; + } + } + + if (g_ShowCommandLineSyntaxAndFail) + { + Printer::Initialize(false, {}); + PrintCommandLineSyntax(); + Printer::Release(); + return PROGRAM_EXIT_ERROR_COMMAND_LINE; + } + + g_PrintAdaptersAsArray = g_ShowAllAdapters || g_UseJsonOutput; + + if (g_OutputToFile) + { + if (!Printer::Initialize(true, g_OutputFilePath)) + { + ErrorPrinter::PrintFormat(L"Could not open file for writing: {}\n", std::make_wformat_args(g_OutputFilePath.c_str())); + return PROGRAM_EXIT_ERROR_INIT; + } + } + else + { + if (!Printer::Initialize(false, {})) + { + assert(0); + return PROGRAM_EXIT_ERROR_INIT; } } - if(g_UseJson) - Json::Begin(); + ReportFormatter::Flags flags = ReportFormatter::Flags::None; + + if (g_UseJsonOutput) + { + flags = flags | ReportFormatter::Flags::UseJson; + } + if (g_UseJsonPrettyPrint) + { + flags = flags | ReportFormatter::Flags::UseJsonPrettyPrint; + } - PrintHeaderData(); + ReportFormatter::CreateInstance(flags); + + if (g_ShowVersionAndQuit) + { + if (IsOutputConsole()) + { + PrintVersionHeader(); + } + else + { + PrintVersionData(); + } + ReportFormatter::DestroyInstance(); + Printer::Release(); + return PROGRAM_EXIT_SUCCESS; + } + + if (g_ShowCommandLineSyntaxAndQuit) + { + PrintCommandLineSyntax(); + ReportFormatter::DestroyInstance(); + Printer::Release(); + return PROGRAM_EXIT_SUCCESS; + } + + PrintVersionData(); #if !defined(AUTO_LINK_DX12) if(!LoadLibraries()) @@ -2028,24 +1873,16 @@ int wmain3(int argc, wchar_t** argv) vkObjPtr = std::make_unique(); #endif - - if(g_UseJson) { - Json::WriteString(L"SystemInfo"); - Json::BeginObject(); - } - else - { - PrintGeneralData(); - } + ReportScopeObject scope(OutputSpecificString(L"System Info", L"SystemInfo")); - if(!g_PureD3D12) - { - PrintOsVersionInfo(); - PrintSystemMemoryInfo(); - } + if(!g_PureD3D12) + { + PrintOsVersionInfo(); + PrintSystemMemoryInfo(); + } - PrintDXGIFeatureInfo(); + PrintDXGIFeatureInfo(); #if USE_NVAPI if(nvApiObjPtr && nvApiObjPtr->IsInitialized()) @@ -2056,15 +1893,11 @@ int wmain3(int argc, wchar_t** argv) agsObjPtr->PrintData(); #endif - EnableExperimentalFeatures(); - - if(g_UseJson) - { - Json::EndObject(); + EnableExperimentalFeatures(); } if(g_PrintEnums) - PrintEnumsData(); + PrintEnums(); int programResult = PROGRAM_EXIT_SUCCESS; @@ -2078,11 +1911,8 @@ int wmain3(int argc, wchar_t** argv) #endif assert(dxgiFactory != nullptr); - if(g_UseJson) - { - Json::WriteString(L"Adapters"); - Json::BeginArray(); - } + ReportScopeArrayConditional scopeArray(g_PrintAdaptersAsArray, OutputSpecificString(L"Adapter", L"Adapters"), ReportFormatter::ArraySuffix::None); + ReportScopeObjectConditional scopeObject(!g_PrintAdaptersAsArray, L"Adapter"); if(g_ListAdapters) ListAdapters(dxgiFactory.Get(), nvApiObjPtr.get(), agsObjPtr.get(), amdDeviceInfoObjPtr.get(), vkObjPtr.get()); @@ -2095,25 +1925,15 @@ int wmain3(int argc, wchar_t** argv) else InspectAllAdapters(dxgiFactory.Get(), nvApiObjPtr.get(), agsObjPtr.get(), amdDeviceInfoObjPtr.get(), vkObjPtr.get()); } - - if(g_UseJson) - { - Json::EndArray(); - } } #if !defined(AUTO_LINK_DX12) UnloadLibraries(); #endif - if(g_UseJson && programResult == PROGRAM_EXIT_SUCCESS) - { - wstring json = Json::End(); - wprintf(L"%.*s", (int)json.length(), json.data()); - } + ReportFormatter::DestroyInstance(); + Printer::Release(); - fflush(stdout); - fflush(stderr); return programResult; } @@ -2125,16 +1945,12 @@ int wmain2(int argc, wchar_t** argv) } catch(const std::exception& ex) { - fwprintf(stderr, L"ERROR: %hs\n", ex.what()); - fflush(stdout); - fflush(stderr); + ErrorPrinter::PrintFormat("ERROR: {}\n", std::make_format_args(ex.what())); return PROGRAM_EXIT_ERROR_EXCEPTION; } catch(...) { - fwprintf(stderr, L"UNKNOWN ERROR.\n"); - fflush(stdout); - fflush(stderr); + ErrorPrinter::PrintString("UNKNOWN ERROR.\n"); return PROGRAM_EXIT_ERROR_EXCEPTION; } } @@ -2147,9 +1963,7 @@ int wmain(int argc, wchar_t** argv) } __except(EXCEPTION_EXECUTE_HANDLER) { - fwprintf(stderr, L"STRUCTURED EXCEPTION: 0x%08X.\n", GetExceptionCode()); - fflush(stdout); - fflush(stderr); + ErrorPrinter::PrintFormat("STRUCTURED EXCEPTION: 0x{:08X}\n", std::make_format_args(GetExceptionCode())); return PROGRAM_EXIT_ERROR_SEH_EXCEPTION; } } diff --git a/Src/NvApiData.cpp b/Src/NvApiData.cpp index 53b68b8..7d9be50 100644 --- a/Src/NvApiData.cpp +++ b/Src/NvApiData.cpp @@ -8,10 +8,9 @@ License: MIT For more information, see files README.md, LICENSE.txt. */ #include "NvApiData.hpp" -#include "Printing.hpp" #include "Enums.hpp" -#include "Json.hpp" #include "Utils.hpp" +#include "ReportFormatter/ReportFormatter.hpp" // Macro set by Cmake. #if USE_NVAPI @@ -343,6 +342,7 @@ static const EnumItem Enum_NV_ARCH_plus_IMPLEMENTATION_ID[] = { { L"NV_GPU_ARCH_IMPLEMENTATION_GA100", 0x00000170 }, { L"NV_GPU_ARCH_IMPLEMENTATION_GA102", 0x00000172 }, { L"NV_GPU_ARCH_IMPLEMENTATION_GA104", 0x00000174 }, + { L"NV_GPU_ARCH_IMPLEMENTATION_GA106", 0x00000176 }, { L"NV_GPU_ARCH_IMPLEMENTATION_AD102", 0x00000192 }, { L"NV_GPU_ARCH_IMPLEMENTATION_AD103", 0x00000193 }, @@ -547,58 +547,25 @@ static bool FindPhysicalGpuAdapterType(NvPhysicalGpuHandle physicalGpuHandle, NV static void PrintCooperativeVectorProperty(size_t index, const NVAPI_COOPERATIVE_VECTOR_PROPERTIES& props) { - if (g_UseJson) - { - Json::BeginObject(); - } - else - { - PrintIndent(); - wprintf(L"NVAPI_COOPERATIVE_VECTOR_PROPERTIES %zu:\n", index); - ++g_Indent; - } - - Print_hex32(L"version", props.version); - PrintEnum(L"inputType", props.inputType, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); - PrintEnum(L"inputInterpretation", props.inputInterpretation, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); - PrintEnum(L"matrixInterpretation", props.matrixInterpretation, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); - PrintEnum(L"biasInterpretation", props.biasInterpretation, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); - PrintEnum(L"resultType", props.resultType, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); - Print_BOOL(L"transpose", props.transpose); - - if (g_UseJson) - Json::EndObject(); - else - { - --g_Indent; - } + ReportScopeArrayItem scope; + + ReportFormatter::GetInstance().AddFieldHex32(L"version", props.version); + ReportFormatter::GetInstance().AddFieldEnum(L"inputType", props.inputType, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); + ReportFormatter::GetInstance().AddFieldEnum(L"inputInterpretation", props.inputInterpretation, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); + ReportFormatter::GetInstance().AddFieldEnum(L"matrixInterpretation", props.matrixInterpretation, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); + ReportFormatter::GetInstance().AddFieldEnum(L"biasInterpretation", props.biasInterpretation, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); + ReportFormatter::GetInstance().AddFieldEnum(L"resultType", props.resultType, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); + ReportFormatter::GetInstance().AddFieldBool(L"transpose", props.transpose); } static void PrintCooperativeVectorProperties(const std::vector& props) { - if (g_UseJson) - { - Json::WriteString(L"NvAPI_D3D12_GetPhysicalDeviceCooperativeVectorProperties"); - Json::BeginArray(); - } - else - { - PrintHeader(L"NvAPI_D3D12_GetPhysicalDeviceCooperativeVectorProperties", 1); - ++g_Indent; - } + ReportScopeArray scope(L"NvAPI_D3D12_GetPhysicalDeviceCooperativeVectorProperties"); for(size_t i = 0; i < props.size(); ++i) { PrintCooperativeVectorProperty(i, props[i]); } - - if (g_UseJson) - Json::EndArray(); - else - { - --g_Indent; - PrintEmptyLine(); - } } //////////////////////////////////////////////////////////////////////////////// @@ -606,12 +573,12 @@ static void PrintCooperativeVectorProperties(const std::vectorm_Name != nullptr; ++ei) { bool supported = false; if(NvAPI_D3D12_IsNvShaderExtnOpCodeSupported(device, ei->m_Value, &supported) == NVAPI_OK) - Print_BOOL(ei->m_Name, supported); + { + scope.Enable(); + ReportFormatter::GetInstance().AddFieldBool(ei->m_Name, supported); + } } } @@ -686,18 +656,19 @@ void NvAPI_Inititalize_RAII::PrintD3d12DeviceData(ID3D12Device* device) NvU32 threadCount = 0; if(NvAPI_D3D12_GetOptimalThreadCountForMesh(device, &threadCount) == NVAPI_OK) { - ScopedStructRegion region(L"NvAPI_D3D12_GetOptimalThreadCountForMesh"); - Print_uint32(L"pThreadCount", (uint32_t)threadCount); + ReportScopeObject scope(L"NvAPI_D3D12_GetOptimalThreadCountForMesh"); + ReportFormatter::GetInstance().AddFieldUint32(L"pThreadCount", (uint32_t)threadCount); } } { - ScopedStructRegion region(L"NvAPI_D3D12_GetRaytracingCaps"); + ReportScopeObjectConditional scope(L"NvAPI_D3D12_GetRaytracingCaps"); NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAPS threadReorderingCaps = {}; if(NvAPI_D3D12_GetRaytracingCaps(device, NVAPI_D3D12_RAYTRACING_CAPS_TYPE_THREAD_REORDERING, &threadReorderingCaps, sizeof threadReorderingCaps) == NVAPI_OK) { - PrintEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_THREAD_REORDERING", (uint32_t)threadReorderingCaps, + scope.Enable(); + ReportFormatter::GetInstance().AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_THREAD_REORDERING", (uint32_t)threadReorderingCaps, Enum_NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAPS); } @@ -705,7 +676,8 @@ void NvAPI_Inititalize_RAII::PrintD3d12DeviceData(ID3D12Device* device) if(NvAPI_D3D12_GetRaytracingCaps(device, NVAPI_D3D12_RAYTRACING_CAPS_TYPE_OPACITY_MICROMAP, &opacityMicromapCaps, sizeof opacityMicromapCaps) == NVAPI_OK) { - PrintEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_OPACITY_MICROMAP", (uint32_t)opacityMicromapCaps, + scope.Enable(); + ReportFormatter::GetInstance().AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_OPACITY_MICROMAP", (uint32_t)opacityMicromapCaps, Enum_NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS); } @@ -713,7 +685,8 @@ void NvAPI_Inititalize_RAII::PrintD3d12DeviceData(ID3D12Device* device) if(NvAPI_D3D12_GetRaytracingCaps(device, NVAPI_D3D12_RAYTRACING_CAPS_TYPE_DISPLACEMENT_MICROMAP, &displacementMicromapCaps, sizeof displacementMicromapCaps) == NVAPI_OK) { - PrintEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_DISPLACEMENT_MICROMAP", (uint32_t)displacementMicromapCaps, + scope.Enable(); + ReportFormatter::GetInstance().AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_DISPLACEMENT_MICROMAP", (uint32_t)displacementMicromapCaps, Enum_NVAPI_D3D12_RAYTRACING_DISPLACEMENT_MICROMAP_CAPS); } @@ -721,7 +694,8 @@ void NvAPI_Inititalize_RAII::PrintD3d12DeviceData(ID3D12Device* device) NvAPI_D3D12_GetRaytracingCaps(device, NVAPI_D3D12_RAYTRACING_CAPS_TYPE_CLUSTER_OPERATIONS, &caps, sizeof caps) == NVAPI_OK) { - PrintEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_CLUSTER_OPERATIONS", (uint32_t)caps, + scope.Enable(); + ReportFormatter::GetInstance().AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_CLUSTER_OPERATIONS", (uint32_t)caps, Enum_NVAPI_D3D12_RAYTRACING_CLUSTER_OPERATIONS_CAPS); } @@ -729,7 +703,8 @@ void NvAPI_Inititalize_RAII::PrintD3d12DeviceData(ID3D12Device* device) NvAPI_D3D12_GetRaytracingCaps(device, NVAPI_D3D12_RAYTRACING_CAPS_TYPE_PARTITIONED_TLAS, &caps, sizeof caps) == NVAPI_OK) { - PrintEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_PARTITIONED_TLAS", (uint32_t)caps, + scope.Enable(); + ReportFormatter::GetInstance().AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_PARTITIONED_TLAS", (uint32_t)caps, Enum_NVAPI_D3D12_RAYTRACING_PARTITIONED_TLAS_CAPS); } @@ -737,7 +712,8 @@ void NvAPI_Inititalize_RAII::PrintD3d12DeviceData(ID3D12Device* device) NvAPI_D3D12_GetRaytracingCaps(device, NVAPI_D3D12_RAYTRACING_CAPS_TYPE_SPHERES, &caps, sizeof caps) == NVAPI_OK) { - PrintEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_SPHERES", (uint32_t)caps, + scope.Enable(); + ReportFormatter::GetInstance().AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_SPHERES", (uint32_t)caps, Enum_NVAPI_D3D12_RAYTRACING_SPHERES_CAPS); } @@ -745,30 +721,32 @@ void NvAPI_Inititalize_RAII::PrintD3d12DeviceData(ID3D12Device* device) NvAPI_D3D12_GetRaytracingCaps(device, NVAPI_D3D12_RAYTRACING_CAPS_TYPE_LINEAR_SWEPT_SPHERES, &caps, sizeof caps) == NVAPI_OK) { - PrintEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_LINEAR_SWEPT_SPHERES", (uint32_t)caps, + scope.Enable(); + ReportFormatter::GetInstance().AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_LINEAR_SWEPT_SPHERES", (uint32_t)caps, Enum_NVAPI_D3D12_RAYTRACING_LINEAR_SWEPT_SPHERES_CAPS); } } { - ScopedStructRegion region(L"NvAPI_D3D12_QueryWorkstationFeatureProperties"); + ReportScopeObjectConditional scope(L"NvAPI_D3D12_QueryWorkstationFeatureProperties"); NVAPI_D3D12_WORKSTATION_FEATURE_PROPERTIES_PARAMS params = { .version = NVAPI_D3D12_WORKSTATION_FEATURE_PROPERTIES_PARAMS_VER }; params.workstationFeatureType = NV_D3D12_WORKSTATION_FEATURE_TYPE_PRESENT_BARRIER; if(NvAPI_D3D12_QueryWorkstationFeatureProperties(device, ¶ms) == NVAPI_OK) { - Print_BOOL(L"NV_D3D12_WORKSTATION_FEATURE_TYPE_PRESENT_BARRIER - supported", params.supported); + scope.Enable(); + ReportFormatter::GetInstance().AddFieldBool(L"NV_D3D12_WORKSTATION_FEATURE_TYPE_PRESENT_BARRIER - supported", params.supported); } params.workstationFeatureType = NV_D3D12_WORKSTATION_FEATURE_TYPE_RDMA_BAR1_SUPPORT; if(NvAPI_D3D12_QueryWorkstationFeatureProperties(device, ¶ms) == NVAPI_OK) { - Print_BOOL(L"NV_D3D12_WORKSTATION_FEATURE_TYPE_RDMA_BAR1_SUPPORT - supported", params.supported); - if(params.supported) + scope.Enable(); + ReportFormatter::GetInstance().AddFieldBool(L"NV_D3D12_WORKSTATION_FEATURE_TYPE_RDMA_BAR1_SUPPORT - supported", params.supported); + if (params.supported) { - Print_uint64(L"NV_D3D12_WORKSTATION_FEATURE_TYPE_RDMA_BAR1_SUPPORT - rdmaHeapSize", params.rdmaInfo.rdmaHeapSize); - + ReportFormatter::GetInstance().AddFieldUint64(L"NV_D3D12_WORKSTATION_FEATURE_TYPE_RDMA_BAR1_SUPPORT - rdmaHeapSize", params.rdmaInfo.rdmaHeapSize); } } } @@ -777,8 +755,8 @@ void NvAPI_Inititalize_RAII::PrintD3d12DeviceData(ID3D12Device* device) bool appClampNeeded = false; if(NvAPI_D3D12_GetNeedsAppFPBlendClamping(device, &appClampNeeded) == NVAPI_OK) { - ScopedStructRegion region(L"NvAPI_D3D12_GetNeedsAppFPBlendClamping"); - Print_BOOL(L"pAppClampNeeded", appClampNeeded); + ReportScopeObject scope(L"NvAPI_D3D12_GetNeedsAppFPBlendClamping"); + ReportFormatter::GetInstance().AddFieldBool(L"pAppClampNeeded", appClampNeeded); } } @@ -794,25 +772,6 @@ void NvAPI_Inititalize_RAII::PrintD3d12DeviceData(ID3D12Device* device) } } -// Prints only implementationId as the numerical value, but searches enum -// using architectureId + implementationId. -static void PrintNvImplementationId(const wchar_t* name, uint32_t architectureId, uint32_t implementationId) -{ - if(g_UseJson) - Print_uint32(name, implementationId); - else - { - PrintIndent(); - PrintName(name); - const wchar_t* enumItemName = FindEnumItemName(architectureId + implementationId, - Enum_NV_ARCH_plus_IMPLEMENTATION_ID); - if(enumItemName != nullptr) - wprintf(L" = %s (0x%X)\n", enumItemName, implementationId); - else - wprintf(L" = 0x%X\n", implementationId); - } -} - void NvAPI_Inititalize_RAII::PrintPhysicalGpuData(const LUID& adapterLuid) { assert(m_Initialized); @@ -823,71 +782,69 @@ void NvAPI_Inititalize_RAII::PrintPhysicalGpuData(const LUID& adapterLuid) if(!FindPhysicalGpu(adapterLuid, gpu)) return; - ScopedStructRegion region(L"NvPhysicalGpuHandle"); + ReportScopeObject scope(L"NvPhysicalGpuHandle"); if(NV_ADAPTER_TYPE adapterType; FindPhysicalGpuAdapterType(gpu, adapterType)) { - PrintFlags(L"adapterType", (uint32_t)adapterType, Enum_NV_ADAPTER_TYPE); + ReportFormatter::GetInstance().AddFieldFlags(L"adapterType", (uint32_t)adapterType, Enum_NV_ADAPTER_TYPE); } NV_SYSTEM_TYPE systemType = {}; if(NvAPI_GPU_GetSystemType(gpu, &systemType) == NVAPI_OK) - PrintEnum(L"NvAPI_GPU_GetSystemType", systemType, Enum_NV_SYSTEM_TYPE); + ReportFormatter::GetInstance().AddFieldEnum(L"NvAPI_GPU_GetSystemType", systemType, Enum_NV_SYSTEM_TYPE); NvAPI_ShortString name = {}; if(NvAPI_GPU_GetFullName(gpu, name) == NVAPI_OK) - Print_string(L"NvAPI_GPU_GetFullName", StrToWstr(name, CP_ACP).c_str()); + ReportFormatter::GetInstance().AddFieldString(L"NvAPI_GPU_GetFullName", StrToWstr(name, CP_ACP).c_str()); NvU32 DeviceId = 0, SubSystemId = 0, RevisionId = 0, ExtDeviceId = 0; if(NvAPI_GPU_GetPCIIdentifiers(gpu, &DeviceId, &SubSystemId, &RevisionId, &ExtDeviceId) == NVAPI_OK) { - Print_hex32(L"NvAPI_GPU_GetPCIIdentifiers - pDeviceID", DeviceId); - PrintSubsystemId(L"NvAPI_GPU_GetPCIIdentifiers - pSubSystemId", SubSystemId); - Print_hex32(L"NvAPI_GPU_GetPCIIdentifiers - pRevisionId", RevisionId); - Print_hex32(L"NvAPI_GPU_GetPCIIdentifiers - pExtDeviceId", ExtDeviceId); + ReportFormatter::GetInstance().AddFieldHex32(L"NvAPI_GPU_GetPCIIdentifiers - pDeviceID", DeviceId); + ReportFormatter::GetInstance().AddFieldSubsystemId(L"NvAPI_GPU_GetPCIIdentifiers - pSubSystemId", SubSystemId); + ReportFormatter::GetInstance().AddFieldHex32(L"NvAPI_GPU_GetPCIIdentifiers - pRevisionId", RevisionId); + ReportFormatter::GetInstance().AddFieldHex32(L"NvAPI_GPU_GetPCIIdentifiers - pExtDeviceId", ExtDeviceId); } NV_GPU_TYPE gpuType = {}; if(NvAPI_GPU_GetGPUType(gpu, &gpuType) == NVAPI_OK) - PrintEnum(L"NvAPI_GPU_GetGPUType", gpuType, Enum_NV_GPU_TYPE); - + ReportFormatter::GetInstance().AddFieldEnum(L"NvAPI_GPU_GetGPUType", gpuType, Enum_NV_GPU_TYPE); + NV_GPU_BUS_TYPE busType = {}; if(NvAPI_GPU_GetBusType(gpu, &busType) == NVAPI_OK) - PrintEnum(L"NvAPI_GPU_GetBusType", busType, Enum_NV_GPU_BUS_TYPE); + ReportFormatter::GetInstance().AddFieldEnum(L"NvAPI_GPU_GetBusType", busType, Enum_NV_GPU_BUS_TYPE); NvU32 biosRevision = 0; if(NvAPI_GPU_GetVbiosRevision(gpu, &biosRevision) == NVAPI_OK) - Print_uint32(L"NvAPI_GPU_GetVbiosRevision", biosRevision); + ReportFormatter::GetInstance().AddFieldUint32(L"NvAPI_GPU_GetVbiosRevision", biosRevision); NvU32 biosOemRevision = 0; if(NvAPI_GPU_GetVbiosOEMRevision(gpu, &biosOemRevision) == NVAPI_OK) - Print_uint32(L"NvAPI_GPU_GetVbiosOEMRevision", biosOemRevision); + ReportFormatter::GetInstance().AddFieldUint32(L"NvAPI_GPU_GetVbiosOEMRevision", biosOemRevision); NvAPI_ShortString biosVersionString = {}; if(NvAPI_GPU_GetVbiosVersionString(gpu, biosVersionString) == NVAPI_OK) - Print_string(L"NvAPI_GPU_GetVbiosVersionString", StrToWstr(biosVersionString, CP_ACP).c_str()); + ReportFormatter::GetInstance().AddFieldString(L"NvAPI_GPU_GetVbiosVersionString", StrToWstr(biosVersionString, CP_ACP).c_str()); NvU32 physicalFrameBufferSize = 0; if(NvAPI_GPU_GetPhysicalFrameBufferSize(gpu, &physicalFrameBufferSize) == NVAPI_OK) - Print_sizeKilobytes(L"NvAPI_GPU_GetPhysicalFrameBufferSize", physicalFrameBufferSize); + ReportFormatter::GetInstance().AddFieldSizeKilobytes(L"NvAPI_GPU_GetPhysicalFrameBufferSize", physicalFrameBufferSize); NvU32 virtualFrameBufferSize = 0; if(NvAPI_GPU_GetVirtualFrameBufferSize(gpu, &virtualFrameBufferSize) == NVAPI_OK) - Print_sizeKilobytes(L"NvAPI_GPU_GetVirtualFrameBufferSize", virtualFrameBufferSize); + ReportFormatter::GetInstance().AddFieldSizeKilobytes(L"NvAPI_GPU_GetVirtualFrameBufferSize", virtualFrameBufferSize); NV_GPU_ARCH_INFO archInfo = {NV_GPU_ARCH_INFO_VER}; if(NvAPI_GPU_GetArchInfo(gpu, &archInfo) == NVAPI_OK) { - PrintEnum(L"NvAPI_GPU_GetArchInfo - NV_GPU_ARCH_INFO::architecture_id", archInfo.architecture_id, Enum_NV_GPU_ARCHITECTURE_ID); - PrintNvImplementationId(L"NvAPI_GPU_GetArchInfo - NV_GPU_ARCH_INFO::implementation_id", - (uint32_t)archInfo.architecture_id, - (uint32_t)archInfo.implementation_id); - PrintEnum(L"NvAPI_GPU_GetArchInfo - NV_GPU_ARCH_INFO::revision_id", archInfo.revision_id, Enum_NV_GPU_CHIP_REVISION); + ReportFormatter::GetInstance().AddFieldEnum(L"NvAPI_GPU_GetArchInfo - NV_GPU_ARCH_INFO::architecture_id", archInfo.architecture_id, Enum_NV_GPU_ARCHITECTURE_ID); + ReportFormatter::GetInstance().AddFieldNvidiaImplementationID(L"NvAPI_GPU_GetArchInfo - NV_GPU_ARCH_INFO::implementation_id", (uint32_t)archInfo.architecture_id, (uint32_t)archInfo.implementation_id, Enum_NV_ARCH_plus_IMPLEMENTATION_ID); + ReportFormatter::GetInstance().AddFieldEnum(L"NvAPI_GPU_GetArchInfo - NV_GPU_ARCH_INFO::revision_id", archInfo.revision_id, Enum_NV_GPU_CHIP_REVISION); } NV_GPU_VR_READY vrReady = {NV_GPU_VR_READY_VER}; if(NvAPI_GPU_GetVRReadyData(gpu, &vrReady) == NVAPI_OK) - Print_BOOL(L"NvAPI_GPU_GetVRReadyData - NV_GPU_VR_READY::isVRReady", vrReady.isVRReady != 0); + ReportFormatter::GetInstance().AddFieldBool(L"NvAPI_GPU_GetVRReadyData - NV_GPU_VR_READY::isVRReady", vrReady.isVRReady != 0); NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM queryIlluminationSupportParm = { .version = NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM_VER, @@ -897,7 +854,7 @@ void NvAPI_Inititalize_RAII::PrintPhysicalGpuData(const LUID& adapterLuid) queryIlluminationSupportParm.Attribute = (NV_GPU_ILLUMINATION_ATTRIB)ei->m_Value; if(NvAPI_GPU_QueryIlluminationSupport(&queryIlluminationSupportParm) == NVAPI_OK) { - Print_BOOL(std::format(L"NvAPI_GPU_QueryIlluminationSupport({})", ei->m_Name).c_str(), + ReportFormatter::GetInstance().AddFieldBool(std::format(L"NvAPI_GPU_QueryIlluminationSupport({})", ei->m_Name).c_str(), queryIlluminationSupportParm.bSupported != 0); } } @@ -905,56 +862,56 @@ void NvAPI_Inititalize_RAII::PrintPhysicalGpuData(const LUID& adapterLuid) for(const EnumItem* ei = Enum_NV_GPU_WORKSTATION_FEATURE_TYPE; ei->m_Name != nullptr; ++ei) { NvAPI_Status status = NvAPI_GPU_QueryWorkstationFeatureSupport(gpu, (NV_GPU_WORKSTATION_FEATURE_TYPE)ei->m_Value); - PrintEnum(std::format(L"NvAPI_GPU_QueryWorkstationFeatureSupport({})", ei->m_Name).c_str(), - status, Enum_NvAPI_Status, true); + ReportFormatter::GetInstance().AddFieldEnumSigned(std::format(L"NvAPI_GPU_QueryWorkstationFeatureSupport({})", ei->m_Name).c_str(), + status, Enum_NvAPI_Status); } { NV_GPU_MEMORY_INFO_EX memInfo = {NV_GPU_MEMORY_INFO_EX_VER}; if(NvAPI_GPU_GetMemoryInfoEx(gpu, &memInfo) == NVAPI_OK) { - Print_size(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemory", memInfo.dedicatedVideoMemory); - Print_size(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::availableDedicatedVideoMemory", memInfo.availableDedicatedVideoMemory); - Print_size(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::systemVideoMemory", memInfo.systemVideoMemory); - Print_size(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::sharedSystemMemory", memInfo.sharedSystemMemory); - Print_size(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::curAvailableDedicatedVideoMemory", memInfo.curAvailableDedicatedVideoMemory); - Print_size(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemoryEvictionsSize", memInfo.dedicatedVideoMemoryEvictionsSize); - Print_uint64(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemoryEvictionCount", memInfo.dedicatedVideoMemoryEvictionCount); - Print_size(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemoryPromotionsSize", memInfo.dedicatedVideoMemoryPromotionsSize); - Print_uint64(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemoryPromotionCount", memInfo.dedicatedVideoMemoryPromotionCount); + ReportFormatter::GetInstance().AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemory", memInfo.dedicatedVideoMemory); + ReportFormatter::GetInstance().AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::availableDedicatedVideoMemory", memInfo.availableDedicatedVideoMemory); + ReportFormatter::GetInstance().AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::systemVideoMemory", memInfo.systemVideoMemory); + ReportFormatter::GetInstance().AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::sharedSystemMemory", memInfo.sharedSystemMemory); + ReportFormatter::GetInstance().AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::curAvailableDedicatedVideoMemory", memInfo.curAvailableDedicatedVideoMemory); + ReportFormatter::GetInstance().AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemoryEvictionsSize", memInfo.dedicatedVideoMemoryEvictionsSize); + ReportFormatter::GetInstance().AddFieldUint64(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemoryEvictionCount", memInfo.dedicatedVideoMemoryEvictionCount); + ReportFormatter::GetInstance().AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemoryPromotionsSize", memInfo.dedicatedVideoMemoryPromotionsSize); + ReportFormatter::GetInstance().AddFieldUint64(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemoryPromotionCount", memInfo.dedicatedVideoMemoryPromotionCount); } } NvU32 shaderSubPipeCount = 0; if(NvAPI_GPU_GetShaderSubPipeCount(gpu, &shaderSubPipeCount) == NVAPI_OK) - Print_uint32(L"NvAPI_GPU_GetShaderSubPipeCount", shaderSubPipeCount); + ReportFormatter::GetInstance().AddFieldUint32(L"NvAPI_GPU_GetShaderSubPipeCount", shaderSubPipeCount); NvU32 gpuCoreCount = 0; if(NvAPI_GPU_GetGpuCoreCount(gpu, &gpuCoreCount) == NVAPI_OK) - Print_uint32(L"NvAPI_GPU_GetGpuCoreCount", gpuCoreCount); + ReportFormatter::GetInstance().AddFieldUint32(L"NvAPI_GPU_GetGpuCoreCount", gpuCoreCount); NV_GPU_ECC_STATUS_INFO GPUECCStatusInfo = {NV_GPU_ECC_STATUS_INFO_VER}; if(NvAPI_GPU_GetECCStatusInfo(gpu, &GPUECCStatusInfo) == NVAPI_OK) { - Print_BOOL(L"NvAPI_GPU_GetECCStatusInfo - NV_GPU_ECC_STATUS_INFO::isSupported", GPUECCStatusInfo.isSupported != 0); - PrintEnum(L"NvAPI_GPU_GetECCStatusInfo - NV_GPU_ECC_STATUS_INFO::configurationOptions", GPUECCStatusInfo.configurationOptions, + ReportFormatter::GetInstance().AddFieldBool(L"NvAPI_GPU_GetECCStatusInfo - NV_GPU_ECC_STATUS_INFO::isSupported", GPUECCStatusInfo.isSupported != 0); + ReportFormatter::GetInstance().AddFieldEnum(L"NvAPI_GPU_GetECCStatusInfo - NV_GPU_ECC_STATUS_INFO::configurationOptions", GPUECCStatusInfo.configurationOptions, Enum_NV_ECC_CONFIGURATION); - Print_BOOL(L"NvAPI_GPU_GetECCStatusInfo - NV_GPU_ECC_STATUS_INFO::isEnabled", GPUECCStatusInfo.isEnabled != 0); + ReportFormatter::GetInstance().AddFieldBool(L"NvAPI_GPU_GetECCStatusInfo - NV_GPU_ECC_STATUS_INFO::isEnabled", GPUECCStatusInfo.isEnabled != 0); } { NvU32 busWidth = 0; if(NvAPI_GPU_GetRamBusWidth(gpu, &busWidth) == NVAPI_OK) - Print_uint32(L"NvAPI_GPU_GetRamBusWidth", busWidth); + ReportFormatter::GetInstance().AddFieldUint32(L"NvAPI_GPU_GetRamBusWidth", busWidth); } { NV_GPU_INFO gpuInfo = {NV_GPU_INFO_VER}; if(NvAPI_GPU_GetGPUInfo(gpu, &gpuInfo) == NVAPI_OK) { - Print_BOOL(L"NvAPI_GPU_GetGPUInfo - NV_GPU_INFO::bIsExternalGpu", gpuInfo.bIsExternalGpu); - Print_uint32(L"NvAPI_GPU_GetGPUInfo - NV_GPU_INFO::rayTracingCores", gpuInfo.rayTracingCores); - Print_uint32(L"NvAPI_GPU_GetGPUInfo - NV_GPU_INFO::tensorCores", gpuInfo.tensorCores); + ReportFormatter::GetInstance().AddFieldBool(L"NvAPI_GPU_GetGPUInfo - NV_GPU_INFO::bIsExternalGpu", gpuInfo.bIsExternalGpu); + ReportFormatter::GetInstance().AddFieldUint32(L"NvAPI_GPU_GetGPUInfo - NV_GPU_INFO::rayTracingCores", gpuInfo.rayTracingCores); + ReportFormatter::GetInstance().AddFieldUint32(L"NvAPI_GPU_GetGPUInfo - NV_GPU_INFO::tensorCores", gpuInfo.tensorCores); } } @@ -962,7 +919,7 @@ void NvAPI_Inititalize_RAII::PrintPhysicalGpuData(const LUID& adapterLuid) NV_GPU_GSP_INFO gspInfo = {NV_GPU_GSP_INFO_VER}; if(NvAPI_GPU_GetGspFeatures(gpu, &gspInfo) == NVAPI_OK) { - PrintHexBytes(L"NvAPI_GPU_GetGspFeatures - NV_GPU_GSP_INFO::firmwareVersion", + ReportFormatter::GetInstance().AddFieldHexBytes(L"NvAPI_GPU_GetGspFeatures - NV_GPU_GSP_INFO::firmwareVersion", gspInfo.firmwareVersion, NVAPI_GPU_MAX_BUILD_VERSION_LENGTH); } } diff --git a/Src/Printer.cpp b/Src/Printer.cpp new file mode 100644 index 0000000..71af1d4 --- /dev/null +++ b/Src/Printer.cpp @@ -0,0 +1,104 @@ +/* +This file is part of D3d12info project: +https://github.com/sawickiap/D3d12info + +Copyright (c) 2018-2025 Adam Sawicki, https://asawicki.info +License: MIT + +For more information, see files README.md, LICENSE.txt. +*/ +#include "Printer.hpp" + +#include +#include + +bool Printer::m_IsInitialized = false; +bool Printer::m_WritingToFile = false; +std::wostream* Printer::m_Output = nullptr; + +bool Printer::Initialize(bool writeToFile, std::wstring_view name) +{ + assert(!m_IsInitialized); + if (writeToFile) + { + m_Output = new std::wofstream(name.data(), std::ios_base::out); + if (!m_Output->good()) + { + delete m_Output; + m_Output = nullptr; + return false; + } + } + else + { + m_Output = &std::wcout; + } + m_IsInitialized = true; + return true; +} + +void Printer::Release() +{ + assert(m_IsInitialized); + if (m_WritingToFile) + { + delete m_Output; + } + m_Output = nullptr; + m_WritingToFile = false; + m_IsInitialized = false; +} + +void Printer::PrintNewLine() +{ + assert(m_IsInitialized); + *m_Output << std::endl; +} + +void Printer::PrintString(std::string_view line) +{ + assert(m_IsInitialized); + + *m_Output << line.data(); +} + +void Printer::PrintString(std::wstring_view line) +{ + assert(m_IsInitialized); + + *m_Output << line; +} + +void Printer::PrintFormat(std::string_view format, std::format_args&& args) +{ + std::string formatted = std::vformat(format, args); + PrintString(formatted); +} + +void Printer::PrintFormat(std::wstring_view format, std::wformat_args&& args) +{ + std::wstring formatted = std::vformat(format, args); + PrintString(formatted); +} + +void ErrorPrinter::PrintFormat(std::string_view format, std::format_args&& args) +{ + std::string formatted = std::vformat(format, args); + PrintString(formatted); +} + +void ErrorPrinter::PrintFormat(std::wstring_view format, std::wformat_args&& args) +{ + std::wstring formatted = std::vformat(format, args); + PrintString(formatted); +} + +void ErrorPrinter::PrintString(std::string_view line) +{ + std::cerr << line; +} + +void ErrorPrinter::PrintString(std::wstring_view line) +{ + std::wcerr << line; +} diff --git a/Src/Printer.hpp b/Src/Printer.hpp new file mode 100644 index 0000000..e4ce46d --- /dev/null +++ b/Src/Printer.hpp @@ -0,0 +1,43 @@ +/* +This file is part of D3d12info project: +https://github.com/sawickiap/D3d12info + +Copyright (c) 2018-2025 Adam Sawicki, https://asawicki.info +License: MIT + +For more information, see files README.md, LICENSE.txt. +*/ + +#pragma once + +#include + +class Printer +{ +public: + static bool Initialize(bool writeToFile, std::wstring_view name); + static void Release(); + + static void PrintNewLine(); + + static void PrintString(std::string_view line); + static void PrintString(std::wstring_view line); + + static void PrintFormat(std::string_view format, std::format_args&& args); + static void PrintFormat(std::wstring_view format, std::wformat_args&& args); + +private: + static bool m_IsInitialized; + static bool m_WritingToFile; + static std::wostream* m_Output; +}; + +class ErrorPrinter +{ +public: + static void PrintString(std::string_view line); + static void PrintString(std::wstring_view line); + + static void PrintFormat(std::string_view format, std::format_args&& args); + static void PrintFormat(std::wstring_view format, std::wformat_args&& args); +}; diff --git a/Src/Printing.cpp b/Src/Printing.cpp deleted file mode 100644 index 8f8dc48..0000000 --- a/Src/Printing.cpp +++ /dev/null @@ -1,380 +0,0 @@ -/* -This file is part of D3d12info project: -https://github.com/sawickiap/D3d12info - -Copyright (c) 2018-2024 Adam Sawicki, https://asawicki.info -License: MIT - -For more information, see files README.md, LICENSE.txt. -*/ -#include "Printing.hpp" -#include "Json.hpp" -#include "Utils.hpp" -#include "Enums.hpp" - -//////////////////////////////////////////////////////////////////////////////// -// PRIVATE - -//////////////////////////////////////////////////////////////////////////////// -// PUBLIC - -bool g_UseJson = false; -uint32_t g_Indent = 0; - -void PrintEmptyLine() -{ - assert(!g_UseJson); - wprintf(L"\n"); -} - -void PrintHeader(const wchar_t* s, uint8_t headerLevel) -{ - assert(!g_UseJson); - assert(headerLevel < 2); - - const size_t len = wcslen(s); - assert(len > 0 && len < 80); - PrintIndent(); - wprintf(L"%s:\n", s); - static const wchar_t* underline1 = L"================================================================================"; - static const wchar_t* underline2 = L"--------------------------------------------------------------------------------"; - const wchar_t* const currUnderline = headerLevel == 0 ? underline1 : underline2; - PrintIndent(); - wprintf(L"%s\n", currUnderline + 80 - len - 1); -} - -void PrintIndent() -{ - assert(!g_UseJson); - if(g_Indent == 0) - return; - static const wchar_t* maxIndentStr = L" "; - const uint32_t offset = 64u - (g_Indent * 4u); - assert(offset < wcslen(maxIndentStr)); - wprintf(L"%s", maxIndentStr + offset); -} - -void PrintName(const wchar_t* name) -{ - assert(!g_UseJson); - wprintf(L"%s", name); -} - -void Print_string(const wchar_t* name, const wchar_t* value) -{ - if(g_UseJson) - { - Json::WriteNameAndString(name, value); - } - else - { - PrintIndent(); - PrintName(name); - wprintf(L" = %s\n", value); - } -} - -void PrintStructBegin(const wchar_t* structName) -{ - if(g_UseJson) - { - Json::WriteString(structName); - Json::BeginObject(); - } - else - { - PrintHeader(structName, 1); - ++g_Indent; - } -} - -void PrintStructEnd() -{ - if(g_UseJson) - { - Json::EndObject(); - } - else - { - --g_Indent; - PrintEmptyLine(); - } -} - -void Print_BOOL(const wchar_t* name, BOOL value) -{ - if(g_UseJson) - { - Json::WriteNameAndBool(name, value != FALSE); - } - else - { - PrintIndent(); - PrintName(name); - wprintf(L" = %s\n", value ? L"TRUE" : L"FALSE"); - } -} - -void Print_uint32(const wchar_t* name, uint32_t value, const wchar_t* unit) -{ - if(g_UseJson) - { - Json::WriteNameAndNumber(name, value); - } - else - { - PrintIndent(); - PrintName(name); - if(unit && *unit) - wprintf(L" = %u %s\n", value, unit); - else - wprintf(L" = %u\n", value); - } -} - -void Print_uint64(const wchar_t* name, uint64_t value, const wchar_t* unit) -{ - if(g_UseJson) - { - Json::WriteNameAndNumber(name, value); - } - else - { - PrintIndent(); - PrintName(name); - if(unit && *unit) - wprintf(L" = %llu %s\n", value, unit); - else - wprintf(L" = %llu\n", value); - } -} - -void Print_size(const wchar_t* name, uint64_t value) -{ - if(g_UseJson) - { - Json::WriteNameAndNumber(name, value); - } - else - { - PrintIndent(); - PrintName(name); - if(value == 0) - wprintf(L" = 0\n"); - else if(value < 1024) - wprintf(L" = %zu (0x%llx)\n", value, value); - else - wprintf(L" = %zu (0x%llx) (%s)\n", value, value, SizeToStr(value).c_str()); - } -} - -void Print_sizeKilobytes(const wchar_t* name, uint64_t value) -{ - if(g_UseJson) - { - Json::WriteNameAndNumber(name, value); - } - else - { - PrintIndent(); - PrintName(name); - if(value == 0) - wprintf(L" = 0 KB\n"); - else if(value < 1024) - wprintf(L" = %zu (0x%llx) KB\n", value, value); - else - wprintf(L" = %zu (0x%llx) KB (%s)\n", value, value, SizeToStr(value * 1024llu).c_str()); - } -} - -void Print_hex32(const wchar_t* name, uint32_t value) -{ - if(g_UseJson) - { - Json::WriteNameAndNumber(name, value); - } - else - { - PrintIndent(); - PrintName(name); - wprintf(L" = 0x%X\n", value); - } -} - -void Print_int32(const wchar_t* name, int32_t value, const wchar_t* unit) -{ - if(g_UseJson) - { - Json::WriteNameAndNumber(name, value); - } - else - { - PrintIndent(); - PrintName(name); - if(unit && *unit) - wprintf(L" = %i %s\n", value, unit); - else - wprintf(L" = %i\n", value); - } -} - -void Print_float(const wchar_t* name, float value, const wchar_t* unit) -{ - if(g_UseJson) - { - Json::WriteNameAndNumber(name, value); - } - else - { - PrintIndent(); - PrintName(name); - if(unit && *unit) - wprintf(L" = %g %s\n", value, unit); - else - wprintf(L" = %g\n", value); - } -} - -void PrintEnum(const wchar_t* name, uint32_t value, const EnumItem* enumItems, bool isSigned) -{ - if(g_UseJson) - { - Json::WriteString(name); - if(isSigned) - Json::WriteNumber((int32_t)value); - else - Json::WriteNumber(value); - } - else - { - PrintIndent(); - PrintName(name); - const wchar_t* enumItemName = FindEnumItemName(value, enumItems); - if(isSigned) - { - if(enumItemName != nullptr) - wprintf(L" = %s (%d)\n", enumItemName, value); - else - wprintf(L" = %d\n", value); - } - else - { - if(enumItemName != nullptr) - wprintf(L" = %s (0x%X)\n", enumItemName, value); - else - wprintf(L" = 0x%X\n", value); - } - } -} - -void PrintFlags(const wchar_t* name, uint32_t value, const EnumItem* enumItems) -{ - if(g_UseJson) - { - Json::WriteNameAndNumber(name, value); - } - else - { - PrintIndent(); - PrintName(name); - wprintf(L" = 0x%X\n", value); - - ++g_Indent; - size_t zeroFlagIndex = SIZE_MAX; - for(size_t i = 0; enumItems[i].m_Name != nullptr; ++i) - { - if(enumItems[i].m_Value == 0) - { - zeroFlagIndex = i; - } - else - { - if((value & enumItems[i].m_Value) != 0) - { - PrintIndent(); - wprintf(L"%s\n", enumItems[i].m_Name); - } - } - } - if(value == 0 && zeroFlagIndex != SIZE_MAX) - { - PrintIndent(); - wprintf(L"%s\n", enumItems[zeroFlagIndex].m_Name); - } - --g_Indent; - } -} - -void PrintHexBytes(const wchar_t* name, const void* data, size_t byteCount) -{ - wstring valStr; - for(size_t i = 0; i < byteCount; ++i) - valStr += std::format(L"{:02X}", *((const uint8_t*)data + i)); - Print_string(name, valStr.c_str()); -} - -void PrintFormat(const wchar_t* name, const wchar_t* format, ...) { - va_list argList; - va_start(argList, format); - wchar_t buffer[256]; - _vsnwprintf_s(buffer, ARRAYSIZE(buffer), format, argList); - va_end(argList); - Print_string(name, buffer); -} - -static bool DecodeAcpiIdChars(wchar_t out[4], uint32_t value) -{ - for(uint32_t i = 0; i < 4; ++i) - { - const uint8_t charValue = (uint8_t)(value >> (i * 8)); - if(charValue < 32 || charValue > 126) - return false; - out[i] = (wchar_t)charValue; - } - return true; -} - -void PrintVendorId(const wchar_t* name, uint32_t value) -{ - wchar_t chars[5] = {}; - if(!g_UseJson && value <= 0xFFFF && DecodeAcpiIdChars(chars, value)) - { - PrintIndent(); - PrintName(name); - const wchar_t* const enumItemName = FindEnumItemName(value, Enum_VendorId); - if(enumItemName != nullptr) - wprintf(L" = %s \"%s\" (0x%X)\n", enumItemName, chars, value); - else - wprintf(L" = \"%s\" 0x%X\n", chars, value); - } - else - { - PrintEnum(name, value, Enum_VendorId); - } -} - -void PrintSubsystemId(const wchar_t* name, uint32_t value) -{ - if(g_UseJson) - PrintEnum(name, value, Enum_SubsystemVendorId); - else - { - PrintIndent(); - PrintName(name); - const wchar_t* enumItemName = FindEnumItemName(value & 0xFFFF, Enum_SubsystemVendorId); - if(enumItemName != nullptr) - wprintf(L" = %s (0x%X)\n", enumItemName, value); - else - wprintf(L" = 0x%X\n", value); - } -} - -ScopedStructRegion::ScopedStructRegion(const wchar_t* name) -{ - PrintStructBegin(name); -} - -ScopedStructRegion::~ScopedStructRegion() -{ - PrintStructEnd(); -} diff --git a/Src/Printing.hpp b/Src/Printing.hpp deleted file mode 100644 index 38a8caa..0000000 --- a/Src/Printing.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/* -This file is part of D3d12info project: -https://github.com/sawickiap/D3d12info - -Copyright (c) 2018-2024 Adam Sawicki, https://asawicki.info -License: MIT - -For more information, see files README.md, LICENSE.txt. -*/ -#pragma once - -struct EnumItem; - -extern bool g_UseJson; -extern uint32_t g_Indent; - -void PrintEmptyLine(); -void PrintHeader(const wchar_t* s, uint8_t headerLevel); -void PrintIndent(); -void PrintName(const wchar_t* name); -void Print_string(const wchar_t* name, const wchar_t* value); -void PrintStructBegin(const wchar_t* structName); -void PrintStructEnd(); -void Print_BOOL(const wchar_t* name, BOOL value); -void Print_uint32(const wchar_t* name, uint32_t value, const wchar_t* unit = nullptr); -void Print_uint64(const wchar_t* name, uint64_t value, const wchar_t* unit = nullptr); -void Print_size(const wchar_t* name, uint64_t value); -void Print_sizeKilobytes(const wchar_t* name, uint64_t value); -void Print_hex32(const wchar_t* name, uint32_t value); -void Print_int32(const wchar_t* name, int32_t value, const wchar_t* unit = nullptr); -void Print_float(const wchar_t* name, float value, const wchar_t* unit = nullptr); -void PrintEnum(const wchar_t* name, uint32_t value, const EnumItem* enumItems, bool isSigned = false); -void PrintFlags(const wchar_t* name, uint32_t value, const EnumItem* enumItems); -void PrintHexBytes(const wchar_t* name, const void* data, size_t byteCount); -void PrintFormat(const wchar_t* name, const wchar_t* format, ...); -void PrintVendorId(const wchar_t* name, uint32_t value); -void PrintSubsystemId(const wchar_t* name, uint32_t value); - -struct ScopedStructRegion -{ -public: - ScopedStructRegion(const wchar_t* name); - ~ScopedStructRegion(); -}; diff --git a/Src/ReportFormatter/ConsoleReportFormatter.cpp b/Src/ReportFormatter/ConsoleReportFormatter.cpp new file mode 100644 index 0000000..56f6d5c --- /dev/null +++ b/Src/ReportFormatter/ConsoleReportFormatter.cpp @@ -0,0 +1,416 @@ +/* +This file is part of D3d12info project: +https://github.com/sawickiap/D3d12info + +Copyright (c) 2018-2025 Adam Sawicki, https://asawicki.info +License: MIT + +For more information, see files README.md, LICENSE.txt. +*/ +#include "ConsoleReportFormatter.hpp" + +#include "Printer.hpp" +#include "Enums.hpp" + +ConsoleReportFormatter::ConsoleReportFormatter(Flags flags) +{ +} + +ConsoleReportFormatter::~ConsoleReportFormatter() +{ + assert(m_ScopeStack.empty()); + Printer::PrintNewLine(); +} + +void ConsoleReportFormatter::PushObject(std::wstring_view name) +{ + assert(!name.empty()); + + // Need to skip new line when outputting first object + if (!m_SkipNewLine) + { + Printer::PrintNewLine(); + Printer::PrintNewLine(); + } + else + { + m_SkipNewLine = false; + } + + PrintIndent(); + + Printer::PrintString(name); + + PrintDivider(name.size()); + + m_ScopeStack.push({ .Type = ScopeType::Object }); + ++m_IndentLevel; +} + +void ConsoleReportFormatter::PushArray(std::wstring_view name, ArraySuffix suffix /* = ArraySuffix::SquareBrackets */) +{ + assert(!name.empty()); + + m_ScopeStack.push({ .ArrayName = std::wstring(name), .Type = ScopeType::Array, .Suffix = suffix }); +} + +void ConsoleReportFormatter::PushArrayItem() +{ + assert(!m_ScopeStack.empty()); + + ScopeInfo& arrayScope = m_ScopeStack.top(); + + assert(arrayScope.Type == ScopeType::Array); + + Printer::PrintNewLine(); + Printer::PrintNewLine(); + PrintIndent(); + + std::wstring header; + switch (arrayScope.Suffix) + { + case ArraySuffix::SquareBrackets: + header = std::format(L"{}[{}]", arrayScope.ArrayName, arrayScope.ElementCount++); + break; + default: + assert(0); + [[fallthrough]]; + case ArraySuffix::None: + header = std::format(L"{} {}", arrayScope.ArrayName, arrayScope.ElementCount++); + break; + } + + Printer::PrintString(header); + + PrintDivider(header.size()); + + m_ScopeStack.push({ .ElementCount = 0, .Type = ScopeType::Object }); + ++m_IndentLevel; +} + +void ConsoleReportFormatter::PopScope() +{ + assert(!m_ScopeStack.empty()); + ScopeInfo scope = m_ScopeStack.top(); + m_ScopeStack.pop(); + if (scope.Type != ScopeType::Array) + { + --m_IndentLevel; + } +} + +void ConsoleReportFormatter::AddFieldString(std::wstring_view name, std::wstring_view value) +{ + assert(!name.empty()); + assert(!value.empty()); + PushElement(); + Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, value)); +} + +void ConsoleReportFormatter::AddFieldBool(std::wstring_view name, bool value) +{ + assert(!name.empty()); + PushElement(); + Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, (value ? L"TRUE" : L"FALSE"))); +} + +void ConsoleReportFormatter::AddFieldUint32(std::wstring_view name, uint32_t value, std::wstring_view unit /*= {}*/) +{ + assert(!name.empty()); + PushElement(); + Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, value)); +} + +void ConsoleReportFormatter::AddFieldUint64(std::wstring_view name, uint64_t value, std::wstring_view unit /*= {}*/) +{ + assert(!name.empty()); + PushElement(); + if (unit.empty()) + { + Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, value)); + } + else + { + Printer::PrintFormat(L"{} = {} {}", std::make_wformat_args(name, value, unit)); + } +} + +void ConsoleReportFormatter::AddFieldSize(std::wstring_view name, uint64_t value) +{ + assert(!name.empty()); + PushElement(); + + const wchar_t* units[] = { L"B", L"KiB", L"MiB", L"GiB", L"TiB" }; + + int selectedUnit = 0; + uint64_t scale = 1; + for (; selectedUnit < ARRAYSIZE(units) - 1; ++selectedUnit) + { + if (value / scale < 1024) + { + break; + } + scale = scale << 10; + } + + if (selectedUnit == 0) + { + Printer::PrintFormat(L"{} = {} {}", std::make_wformat_args(name, value, units[selectedUnit])); + return; + } + else + { + Printer::PrintFormat(L"{} = {:.2f} {} ({} B)", std::make_wformat_args(name, double(value) / scale, units[selectedUnit], value)); + } +} + +void ConsoleReportFormatter::AddFieldSizeKilobytes(std::wstring_view name, uint64_t value) +{ + AddFieldSize(name, value * 1024); +} + +void ConsoleReportFormatter::AddFieldHex32(std::wstring_view name, uint32_t value) +{ + assert(!name.empty()); + PushElement(); + Printer::PrintFormat(L"{} = 0x{:X}", std::make_wformat_args(name, value)); +} + +void ConsoleReportFormatter::AddFieldInt32(std::wstring_view name, int32_t value, std::wstring_view unit /*= {}*/) +{ + assert(!name.empty()); + PushElement(); + if (unit.empty()) + { + Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, value)); + } + else + { + Printer::PrintFormat(L"{} = {} {}", std::make_wformat_args(name, value, unit)); + } +} + +void ConsoleReportFormatter::AddFieldFloat(std::wstring_view name, float value, std::wstring_view unit /*= {}*/) +{ + assert(!name.empty()); + PushElement(); + if (unit.empty()) + { + Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, value)); + } + else + { + Printer::PrintFormat(L"{} = {} {}", std::make_wformat_args(name, value, unit)); + } +} + +void ConsoleReportFormatter::AddFieldEnum(std::wstring_view name, uint32_t value, const EnumItem* enumItems) +{ + assert(!name.empty()); + PushElement(); + const wchar_t* enumItemName = FindEnumItemName(value, enumItems); + if (enumItemName == nullptr) + { + enumItemName = L"Unknown"; + } + + Printer::PrintFormat(L"{} = {} (0x{:X})", std::make_wformat_args(name, enumItemName, value)); +} + +void ConsoleReportFormatter::AddFieldEnumSigned(std::wstring_view name, int32_t value, const EnumItem* enumItems) +{ + assert(!name.empty()); + PushElement(); + const wchar_t* enumItemName = FindEnumItemName(value, enumItems); + if (enumItemName == nullptr) + { + enumItemName = L"Unknown"; + } + + Printer::PrintFormat(L"{} = {} ({})", std::make_wformat_args(name, enumItemName, value)); +} + +void ConsoleReportFormatter::AddEnumArray(std::wstring_view name, const uint32_t* values, size_t count, const EnumItem* enumItems) +{ + assert(!name.empty()); + PushElement(); + Printer::PrintFormat(L"{}", std::make_wformat_args(name)); + ++m_IndentLevel; + for (size_t i = 0; i < count; ++i) + { + Printer::PrintNewLine(); + PrintIndent(); + const wchar_t* enumItemName = FindEnumItemName(values[i], enumItems); + if (enumItemName == nullptr) + { + enumItemName = L"Unknown"; + } + Printer::PrintFormat(L"[{}] = {} (0x{:X})", std::make_wformat_args(i, enumItemName, values[i])); + } + --m_IndentLevel; +} + +void ConsoleReportFormatter::AddFieldFlags(std::wstring_view name, uint32_t value, const EnumItem* enumItems) +{ + assert(!name.empty()); + PushElement(); + Printer::PrintFormat(L"{} = 0x{:X}", std::make_wformat_args(name, value)); + + ++m_IndentLevel; + size_t zeroFlagIndex = SIZE_MAX; + for (size_t i = 0; enumItems[i].m_Name != nullptr; ++i) + { + if (enumItems[i].m_Value == 0) + { + zeroFlagIndex = i; + } + else + { + if ((value & enumItems[i].m_Value) != 0) + { + Printer::PrintNewLine(); + PrintIndent(); + Printer::PrintString(enumItems[i].m_Name); + } + } + } + if (value == 0 && zeroFlagIndex != SIZE_MAX) + { + Printer::PrintNewLine(); + PrintIndent(); + Printer::PrintString(enumItems[zeroFlagIndex].m_Name); + } + --m_IndentLevel; +} + +void ConsoleReportFormatter::AddFieldHexBytes(std::wstring_view name, const void* data, size_t byteCount) +{ + std::wstring valStr; + for (size_t i = 0; i < byteCount; ++i) + { + valStr += std::format(L"{:02X}", *((const uint8_t*)data + i)); + } + AddFieldString(name, valStr); +} + +void ConsoleReportFormatter::AddFieldVendorId(std::wstring_view name, uint32_t value) +{ + assert(!name.empty()); + + auto ACPIIDOpt = DecodeACPIID(value); + + if (ACPIIDOpt.has_value()) + { + PushElement(); + auto& ACPIID = ACPIIDOpt.value(); + const wchar_t* enumItemName = FindEnumItemName(value, Enum_VendorId); + if (enumItemName == nullptr) + { + enumItemName = L"Unknown"; + } + + Printer::PrintFormat(L"{} = {} \"{}\" (0x{:X})", std::make_wformat_args(name, enumItemName, ACPIID, value)); + } + else + { + AddFieldEnum(name, value, Enum_VendorId); + } + +} + +void ConsoleReportFormatter::AddFieldSubsystemId(std::wstring_view name, uint32_t value) +{ + assert(!name.empty()); + PushElement(); + + const wchar_t* enumItemName = FindEnumItemName(value & 0xFFFF, Enum_SubsystemVendorId); + if (enumItemName == nullptr) + { + enumItemName = L"Unknown"; + } + + Printer::PrintFormat(L"{} = {} (0x{:X})", std::make_wformat_args(name, enumItemName, value)); +} + +void ConsoleReportFormatter::AddFieldMicrosoftVersion(std::wstring_view name, uint64_t value) +{ + assert(!name.empty()); + PushElement(); + Printer::PrintFormat(L"{} = {}.{}.{}.{}", std::make_wformat_args(name, value >> 48, (value >> 32) & 0xFFFF, (value >> 16) & 0xFFFF, value & 0xFFFF)); +} + +void ConsoleReportFormatter::AddFieldAMDVersion(std::wstring_view name, uint64_t value) +{ + assert(!name.empty()); + PushElement(); + Printer::PrintFormat(L"{} = {}.{}.{}", std::make_wformat_args(name, value >> 22, (value >> 12) & 0b11'1111'1111, value & 0b1111'1111'1111)); +} + +void ConsoleReportFormatter::AddFieldNvidiaImplementationID(std::wstring_view name, uint32_t architectureId, uint32_t implementationId, const EnumItem* architecturePlusImplementationIDEnum) +{ + // Prints only implementationId as the numerical value, but searches enum + // using architectureId + implementationId. + + assert(!name.empty()); + PushElement(); + + const wchar_t* enumItemName = FindEnumItemName(architectureId + implementationId, + architecturePlusImplementationIDEnum); + if (enumItemName == nullptr) + { + enumItemName = L"Unknown"; + } + + Printer::PrintFormat(L"{} = {} (0x{:X})", std::make_wformat_args(name, enumItemName, implementationId)); +} + +void ConsoleReportFormatter::PrintIndent() const +{ + Printer::PrintString(std::wstring(INDENT_SIZE * m_IndentLevel, INDENT_CHAR)); +} + +void ConsoleReportFormatter::PushElement() +{ + m_ScopeStack.top().ElementCount++; + Printer::PrintNewLine(); + PrintIndent(); +} + +void ConsoleReportFormatter::PrintDivider(size_t size) +{ + Printer::PrintNewLine(); + PrintIndent(); + wchar_t dividerChar; + + switch (m_IndentLevel) + { + case 0: + dividerChar = L'='; + break; + default: + dividerChar = L'-'; + break; + } + + Printer::PrintString(std::wstring(size, dividerChar)); +} + +std::optional ConsoleReportFormatter::DecodeACPIID(uint32_t value) +{ + if (value <= 0xFFFF) + { + return std::nullopt; + } + + std::wstring result; + result.resize(4); + + for (uint32_t i = 0; i < 4; ++i) + { + const uint8_t charValue = (uint8_t)(value >> (i * 8)); + if (charValue < 32 || charValue > 126) + return std::nullopt; + result[i] = (wchar_t)charValue; + } + return result; +} diff --git a/Src/ReportFormatter/ConsoleReportFormatter.hpp b/Src/ReportFormatter/ConsoleReportFormatter.hpp new file mode 100644 index 0000000..c576596 --- /dev/null +++ b/Src/ReportFormatter/ConsoleReportFormatter.hpp @@ -0,0 +1,73 @@ +/* +This file is part of D3d12info project: +https://github.com/sawickiap/D3d12info + +Copyright (c) 2018-2025 Adam Sawicki, https://asawicki.info +License: MIT + +For more information, see files README.md, LICENSE.txt. +*/ + +#pragma once + +#include "ReportFormatter.hpp" +#include +#include + +class ConsoleReportFormatter final : public ReportFormatter +{ +public: + ConsoleReportFormatter(Flags flags); + ~ConsoleReportFormatter(); + + void PushObject(std::wstring_view name) final; + void PushArray(std::wstring_view name, ArraySuffix suffix = ArraySuffix::SquareBrackets); + void PushArrayItem() final; + void PopScope() final; + + void AddFieldString(std::wstring_view name, std::wstring_view value) final; + void AddFieldBool(std::wstring_view name, bool value); + void AddFieldUint32(std::wstring_view name, uint32_t value, std::wstring_view unit = {}) final; + void AddFieldUint64(std::wstring_view name, uint64_t value, std::wstring_view unit = {}) final; + void AddFieldSize(std::wstring_view name, uint64_t value) final; + void AddFieldSizeKilobytes(std::wstring_view name, uint64_t value) final; + void AddFieldHex32(std::wstring_view name, uint32_t value) final; + void AddFieldInt32(std::wstring_view name, int32_t value, std::wstring_view unit = {}) final; + void AddFieldFloat(std::wstring_view name, float value, std::wstring_view unit = {}) final; + void AddFieldEnum(std::wstring_view name, uint32_t value, const EnumItem* enumItems) final; + void AddFieldEnumSigned(std::wstring_view name, int32_t value, const EnumItem* enumItems) final; + void AddEnumArray(std::wstring_view name, const uint32_t* values, size_t count, const EnumItem* enumItems) final; + void AddFieldFlags(std::wstring_view name, uint32_t value, const EnumItem* enumItems) final; + void AddFieldHexBytes(std::wstring_view name, const void* data, size_t byteCount) final; + void AddFieldVendorId(std::wstring_view name, uint32_t value) final; + void AddFieldSubsystemId(std::wstring_view name, uint32_t value) final; + void AddFieldMicrosoftVersion(std::wstring_view name, uint64_t value) final; + void AddFieldAMDVersion(std::wstring_view name, uint64_t value) final; + void AddFieldNvidiaImplementationID(std::wstring_view name, uint32_t architectureId, uint32_t implementationId, const EnumItem* architecturePlusImplementationIDEnum) final; + +private: + static constexpr size_t INDENT_SIZE = 4; + static constexpr wchar_t INDENT_CHAR = L' '; + + enum class ScopeType + { + Object, + Array + }; + struct ScopeInfo + { + std::wstring ArrayName; + size_t ElementCount = 0; + ScopeType Type; + ArraySuffix Suffix; + }; + std::stack m_ScopeStack; + uint32_t m_IndentLevel = 0; + bool m_SkipNewLine = true; + + void PrintIndent() const; + void PushElement(); + void PrintDivider(size_t size); + + static std::optional DecodeACPIID(uint32_t value); +}; diff --git a/Src/ReportFormatter/JSONReportFormatter.cpp b/Src/ReportFormatter/JSONReportFormatter.cpp new file mode 100644 index 0000000..870e6ba --- /dev/null +++ b/Src/ReportFormatter/JSONReportFormatter.cpp @@ -0,0 +1,234 @@ +/* +This file is part of D3d12info project: +https://github.com/sawickiap/D3d12info + +Copyright (c) 2018-2025 Adam Sawicki, https://asawicki.info +License: MIT + +For more information, see files README.md, LICENSE.txt. +*/ +#include "JSONReportFormatter.hpp" + +#include "Printer.hpp" + +JSONReportFormatter::JSONReportFormatter(Flags flags) + : m_PrettyPrint((flags& Flags::UseJsonPrettyPrint) != Flags::None) +{ + Printer::PrintString(L"{"); + m_ScopeStack.push({ .ElementCount = 0, .Type = ScopeType::Object }); +} + +JSONReportFormatter::~JSONReportFormatter() +{ + PopScope(); + PrintNewLine(); + assert(m_ScopeStack.empty()); +} + +void JSONReportFormatter::PushObject(std::wstring_view name) +{ + assert(!name.empty()); + + PushNewElement(); + + Printer::PrintFormat(m_PrettyPrint ? L"\"{}\": {{" : L"\"{}\":{{", std::make_wformat_args(name)); + + m_ScopeStack.push({ .ElementCount = 0, .Type = ScopeType::Object }); +} + +void JSONReportFormatter::PushArray(std::wstring_view name, ArraySuffix suffix /* = ArraySuffix::SquareBrackets */) +{ + assert(!name.empty()); + + PushNewElement(); + + Printer::PrintFormat(m_PrettyPrint ? L"\"{}\": [" : L"\"{}\":[", std::make_wformat_args(name)); + + m_ScopeStack.push({ .ElementCount = 0, .Type = ScopeType::Array }); +} + +void JSONReportFormatter::PushArrayItem() +{ + assert(!m_ScopeStack.empty()); + assert(m_ScopeStack.top().Type == ScopeType::Array); + + PushNewElement(); + + Printer::PrintString(L"{"); + + m_ScopeStack.push({ .ElementCount = 0, .Type = ScopeType::Object }); +} + +void JSONReportFormatter::PopScope() +{ + assert(!m_ScopeStack.empty()); + + ScopeInfo scope = m_ScopeStack.top(); + m_ScopeStack.pop(); + + if (scope.ElementCount != 0) + { + PrintNewLine(); + PrintIndent(); + } + + Printer::PrintString(scope.Type == ScopeType::Object ? L"}" : L"]"); +} + +void JSONReportFormatter::AddFieldString(std::wstring_view name, std::wstring_view value) +{ + assert(!name.empty()); + assert(!value.empty()); + PushNewElement(); + Printer::PrintFormat(m_PrettyPrint ? L"\"{}\": \"{}\"" : L"\"{}\":\"{}\"", std::make_wformat_args(name, value)); +} + +void JSONReportFormatter::AddFieldBool(std::wstring_view name, bool value) +{ + assert(!name.empty()); + PushNewElement(); + Printer::PrintFormat(m_PrettyPrint ? L"\"{}\": {}" : L"\"{}\":{}", std::make_wformat_args(name, value ? L"true" : L"false")); +} + +void JSONReportFormatter::AddFieldUint32(std::wstring_view name, uint32_t value, std::wstring_view unit /* = {}*/) +{ + assert(!name.empty()); + PushNewElement(); + Printer::PrintFormat(m_PrettyPrint ? L"\"{}\": {}" : L"\"{}\":{}", std::make_wformat_args(name, value)); +} + +void JSONReportFormatter::AddFieldUint64(std::wstring_view name, uint64_t value, std::wstring_view unit /* = {}*/) +{ + assert(!name.empty()); + PushNewElement(); + Printer::PrintFormat(m_PrettyPrint ? L"\"{}\": {}" : L"\"{}\":{}", std::make_wformat_args(name, value)); +} + +void JSONReportFormatter::AddFieldSize(std::wstring_view name, uint64_t value) +{ + AddFieldUint64(name, value); +} + +void JSONReportFormatter::AddFieldSizeKilobytes(std::wstring_view name, uint64_t value) +{ + AddFieldUint64(name, value); +} + +void JSONReportFormatter::AddFieldHex32(std::wstring_view name, uint32_t value) +{ + AddFieldUint32(name, value); +} + +void JSONReportFormatter::AddFieldInt32(std::wstring_view name, int32_t value, std::wstring_view unit /* = {}*/) +{ + assert(!name.empty()); + PushNewElement(); + Printer::PrintFormat(m_PrettyPrint ? L"\"{}\": {}" : L"\"{}\":{}", std::make_wformat_args(name, value)); +} + +void JSONReportFormatter::AddFieldFloat(std::wstring_view name, float value, std::wstring_view unit /* = {}*/) +{ + assert(!name.empty()); + PushNewElement(); + Printer::PrintFormat(m_PrettyPrint ? L"\"{}\": {}" : L"\"{}\":{}", std::make_wformat_args(name, value)); +} + +void JSONReportFormatter::AddFieldEnum(std::wstring_view name, uint32_t value, const EnumItem* enumItems) +{ + AddFieldUint32(name, value); +} + +void JSONReportFormatter::AddFieldEnumSigned(std::wstring_view name, int32_t value, const EnumItem* enumItems) +{ + AddFieldInt32(name, value); +} + +void JSONReportFormatter::AddEnumArray(std::wstring_view name, const uint32_t* values, size_t count, const EnumItem* enumItems) +{ + assert(!name.empty()); + PushNewElement(); + Printer::PrintFormat(m_PrettyPrint ? L"\"{}\": [" : L"\"{}\":[", std::make_wformat_args(name)); + for (size_t i = 0; i < count; ++i) + { + if (i > 0) + { + Printer::PrintString(L","); + } + PrintNewLine(); + PrintIndent(1); + Printer::PrintFormat(L"{}", std::make_wformat_args(values[i])); + } + PrintNewLine(); + PrintIndent(); + Printer::PrintString(L"]"); +} + +void JSONReportFormatter::AddFieldFlags(std::wstring_view name, uint32_t value, const EnumItem* enumItems) +{ + AddFieldUint32(name, value); +} + +void JSONReportFormatter::AddFieldHexBytes(std::wstring_view name, const void* data, size_t byteCount) +{ + std::wstring valStr; + for (size_t i = 0; i < byteCount; ++i) + { + valStr += std::format(L"{:02X}", *((const uint8_t*)data + i)); + } + AddFieldString(name, valStr); +} + +void JSONReportFormatter::AddFieldVendorId(std::wstring_view name, uint32_t value) +{ + AddFieldUint32(name, value); +} + +void JSONReportFormatter::AddFieldSubsystemId(std::wstring_view name, uint32_t value) +{ + AddFieldUint32(name, value); +} + +void JSONReportFormatter::AddFieldMicrosoftVersion(std::wstring_view name, uint64_t value) +{ + AddFieldUint64(name, value); +} + +void JSONReportFormatter::AddFieldAMDVersion(std::wstring_view name, uint64_t value) +{ + AddFieldUint64(name, value); +} + +void JSONReportFormatter::AddFieldNvidiaImplementationID(std::wstring_view name, uint32_t architectureId, uint32_t implementationId, const EnumItem* architecturePlusImplementationIDEnum) +{ + AddFieldUint32(name, implementationId); +} + +void JSONReportFormatter::PushNewElement() +{ + if (m_ScopeStack.top().ElementCount > 0) + { + Printer::PrintString(L","); + } + m_ScopeStack.top().ElementCount++; + PrintNewLine(); + PrintIndent(); +} + +void JSONReportFormatter::PrintIndent(size_t additionalIndentation /*= 0*/) +{ + if (!m_PrettyPrint) + { + return; + } + + Printer::PrintString(std::wstring((m_ScopeStack.size() + additionalIndentation) * INDENT_SIZE, INDENT_CHAR)); +} + +void JSONReportFormatter::PrintNewLine() +{ + if (m_PrettyPrint) + { + Printer::PrintNewLine(); + } +} + diff --git a/Src/ReportFormatter/JSONReportFormatter.hpp b/Src/ReportFormatter/JSONReportFormatter.hpp new file mode 100644 index 0000000..11fc254 --- /dev/null +++ b/Src/ReportFormatter/JSONReportFormatter.hpp @@ -0,0 +1,69 @@ +/* +This file is part of D3d12info project: +https://github.com/sawickiap/D3d12info + +Copyright (c) 2018-2025 Adam Sawicki, https://asawicki.info +License: MIT + +For more information, see files README.md, LICENSE.txt. +*/ + +#pragma once + +#include "ReportFormatter.hpp" +#include + +class JSONReportFormatter final : public ReportFormatter +{ +public: + JSONReportFormatter(Flags flags); + ~JSONReportFormatter(); + + void PushObject(std::wstring_view name) final; + void PushArray(std::wstring_view name, ArraySuffix suffix = ArraySuffix::SquareBrackets); + void PushArrayItem() final; + void PopScope() final; + + void AddFieldString(std::wstring_view name, std::wstring_view value) final; + void AddFieldBool(std::wstring_view name, bool value); + void AddFieldUint32(std::wstring_view name, uint32_t value, std::wstring_view unit = {}) final; + void AddFieldUint64(std::wstring_view name, uint64_t value, std::wstring_view unit = {}) final; + void AddFieldSize(std::wstring_view name, uint64_t value) final; + void AddFieldSizeKilobytes(std::wstring_view name, uint64_t value) final; + void AddFieldHex32(std::wstring_view name, uint32_t value) final; + void AddFieldInt32(std::wstring_view name, int32_t value, std::wstring_view unit = {}) final; + void AddFieldFloat(std::wstring_view name, float value, std::wstring_view unit = {}) final; + void AddFieldEnum(std::wstring_view name, uint32_t value, const EnumItem* enumItems) final; + void AddFieldEnumSigned(std::wstring_view name, int32_t value, const EnumItem* enumItems) final; + void AddEnumArray(std::wstring_view name, const uint32_t* values, size_t count, const EnumItem* enumItems) final; + void AddFieldFlags(std::wstring_view name, uint32_t value, const EnumItem* enumItems) final; + void AddFieldHexBytes(std::wstring_view name, const void* data, size_t byteCount) final; + void AddFieldVendorId(std::wstring_view name, uint32_t value) final; + void AddFieldSubsystemId(std::wstring_view name, uint32_t value) final; + void AddFieldMicrosoftVersion(std::wstring_view name, uint64_t value) final; + void AddFieldAMDVersion(std::wstring_view name, uint64_t value) final; + void AddFieldNvidiaImplementationID(std::wstring_view name, uint32_t architectureId, uint32_t implementationId, const EnumItem* architecturePlusImplementationIDEnum) final; + +private: + static constexpr size_t INDENT_SIZE = 4; + static constexpr wchar_t INDENT_CHAR = L' '; + + enum class ScopeType + { + Object, + Array + }; + + struct ScopeInfo + { + size_t ElementCount; + ScopeType Type; + }; + + bool m_PrettyPrint; + std::stack m_ScopeStack = {}; + + void PushNewElement(); + void PrintIndent(size_t additionalIndentation = 0); + void PrintNewLine(); +}; diff --git a/Src/ReportFormatter/ReportFormatter.cpp b/Src/ReportFormatter/ReportFormatter.cpp new file mode 100644 index 0000000..6852191 --- /dev/null +++ b/Src/ReportFormatter/ReportFormatter.cpp @@ -0,0 +1,230 @@ +/* +This file is part of D3d12info project: +https://github.com/sawickiap/D3d12info + +Copyright (c) 2018-2025 Adam Sawicki, https://asawicki.info +License: MIT + +For more information, see files README.md, LICENSE.txt. +*/ +#include "ReportFormatter.hpp" + +#include "JSONReportFormatter.hpp" +#include "ConsoleReportFormatter.hpp" + +static ReportFormatter* s_Instance = nullptr; +static ReportFormatter::Flags s_Flags = ReportFormatter::Flags::None; + +void ReportFormatter::CreateInstance(Flags flags) +{ + assert(s_Instance == nullptr); + if ((flags & Flags::UseJson) != Flags::None) + { + s_Instance = new JSONReportFormatter(flags); + } + else + { + s_Instance = new ConsoleReportFormatter(flags); + } + s_Flags = flags; +} + +void ReportFormatter::DestroyInstance() +{ + assert(s_Instance != nullptr); + delete s_Instance; + s_Instance = nullptr; +} + +ReportFormatter& ReportFormatter::GetInstance() +{ + assert(s_Instance != nullptr); + return *s_Instance; +} + +ReportFormatter::Flags ReportFormatter::GetFlags() +{ + assert(s_Instance != nullptr); + return s_Flags; +} + +ReportFormatter::Flags operator&(ReportFormatter::Flags a, ReportFormatter::Flags b) +{ + return static_cast(static_cast(a) & static_cast(b)); +} + +ReportFormatter::Flags operator|(ReportFormatter::Flags a, ReportFormatter::Flags b) +{ + return static_cast(static_cast(a) | static_cast(b)); +} + +bool operator||(bool a, ReportFormatter::Flags b) +{ + return a || (b != ReportFormatter::Flags::None); +} + +bool operator&&(bool a, ReportFormatter::Flags b) +{ + return a && (b != ReportFormatter::Flags::None); +} + +bool operator!(ReportFormatter::Flags a) +{ + return a == ReportFormatter::Flags::None; +} + +ReportScopeObject::ReportScopeObject(std::wstring_view name) +{ + ReportFormatter::GetInstance().PushObject(name); +} + +ReportScopeObject::~ReportScopeObject() +{ + ReportFormatter::GetInstance().PopScope(); +} + +ReportScopeArray::ReportScopeArray(std::wstring_view name, ReportFormatter::ArraySuffix suffix /*= ReportFormatter::ArraySuffix::SquareBrackets*/) +{ + ReportFormatter::GetInstance().PushArray(name, suffix); +} + +ReportScopeArray::~ReportScopeArray() +{ + ReportFormatter::GetInstance().PopScope(); +} + +ReportScopeArrayItem::ReportScopeArrayItem() +{ + ReportFormatter::GetInstance().PushArrayItem(); +} + +ReportScopeArrayItem::~ReportScopeArrayItem() +{ + ReportFormatter::GetInstance().PopScope(); +} + +ReportScopeObjectConditional::ReportScopeObjectConditional(std::wstring_view name) + : m_Name(name) +{ +} + +ReportScopeObjectConditional::ReportScopeObjectConditional(bool enable, std::wstring_view name) + : ReportScopeObjectConditional(name) +{ + if (enable) + { + Enable(); + } +} + +ReportScopeObjectConditional::~ReportScopeObjectConditional() +{ + if (m_Enabled) + { + ReportFormatter::GetInstance().PopScope(); + } +} + +void ReportScopeObjectConditional::Enable() +{ + if (!m_Enabled) + { + ReportFormatter::GetInstance().PushObject(m_Name); + m_Enabled = true; + } +} + +ReportScopeArrayConditional::ReportScopeArrayConditional(std::wstring_view name, ReportFormatter::ArraySuffix suffix /*= ReportFormatter::ArraySuffix::SquareBrackets*/) + : m_Name(name) + , m_Suffix(suffix) +{ +} + +ReportScopeArrayConditional::ReportScopeArrayConditional(bool enable, std::wstring_view name, ReportFormatter::ArraySuffix suffix /*= ReportFormatter::ArraySuffix::SquareBrackets*/) + : ReportScopeArrayConditional(name, suffix) +{ + if (enable) + { + Enable(); + } +} + +ReportScopeArrayConditional::~ReportScopeArrayConditional() +{ + if (m_Enabled) + { + ReportFormatter::GetInstance().PopScope(); + } +} + +void ReportScopeArrayConditional::Enable() +{ + if (!m_Enabled) + { + ReportFormatter::GetInstance().PushArray(m_Name, m_Suffix); + m_Enabled = true; + } +} + +ReportScopeArrayItemConditional::ReportScopeArrayItemConditional() +{ +} + +ReportScopeArrayItemConditional::ReportScopeArrayItemConditional(bool enable) +{ + if (enable) + { + Enable(); + } +} + +ReportScopeArrayItemConditional::~ReportScopeArrayItemConditional() +{ + if (m_Enabled) + { + ReportFormatter::GetInstance().PopScope(); + } +} + +void ReportScopeArrayItemConditional::Enable() +{ + if (!m_Enabled) + { + ReportFormatter::GetInstance().PushArrayItem(); + m_Enabled = true; + } +} + +bool IsOutputConsole() +{ + return (ReportFormatter::GetFlags() & ReportFormatter::Flags::UseJson) == ReportFormatter::Flags::None; +} + +bool IsOutputJson() +{ + return !IsOutputConsole(); +} + +std::wstring_view OutputSpecificString(std::wstring_view consoleString, std::wstring_view jsonString) +{ + if ((ReportFormatter::GetFlags() & ReportFormatter::Flags::UseJson) != ReportFormatter::Flags::None) + { + return jsonString; + } + else + { + return consoleString; + } +} + +std::string_view OutputSpecificString(std::string_view consoleString, std::string_view jsonString) +{ + if ((ReportFormatter::GetFlags() & ReportFormatter::Flags::UseJson) != ReportFormatter::Flags::None) + { + return jsonString; + } + else + { + return consoleString; + } +} diff --git a/Src/ReportFormatter/ReportFormatter.hpp b/Src/ReportFormatter/ReportFormatter.hpp new file mode 100644 index 0000000..9d6b90f --- /dev/null +++ b/Src/ReportFormatter/ReportFormatter.hpp @@ -0,0 +1,141 @@ +/* +This file is part of D3d12info project: +https://github.com/sawickiap/D3d12info + +Copyright (c) 2018-2025 Adam Sawicki, https://asawicki.info +License: MIT + +For more information, see files README.md, LICENSE.txt. +*/ + +#pragma once + +#include +#include + +struct EnumItem; + +class ReportFormatter +{ +public: + enum class Flags : uint32_t + { + None = 0, + UseJson = 1 << 0, + UseJsonPrettyPrint = 1 << 1 + }; + + enum class ArraySuffix + { + SquareBrackets, + None + }; + + static void CreateInstance(Flags flags); + static void DestroyInstance(); + static ReportFormatter& GetInstance(); + static Flags GetFlags(); + + virtual ~ReportFormatter() = default; + + virtual void PushObject(std::wstring_view name) = 0; + virtual void PushArray(std::wstring_view name, ArraySuffix suffix = ArraySuffix::SquareBrackets) = 0; + virtual void PushArrayItem() = 0; + virtual void PopScope() = 0; + + // Fields + // Strings + virtual void AddFieldString(std::wstring_view name, std::wstring_view value) = 0; + // Booleans + virtual void AddFieldBool(std::wstring_view name, bool value) = 0; + // Integers + virtual void AddFieldUint32(std::wstring_view name, uint32_t value, std::wstring_view unit = {}) = 0; + virtual void AddFieldUint64(std::wstring_view name, uint64_t value, std::wstring_view unit = {}) = 0; + virtual void AddFieldSize(std::wstring_view name, uint64_t value) = 0; + virtual void AddFieldSizeKilobytes(std::wstring_view name, uint64_t value) = 0; + virtual void AddFieldHex32(std::wstring_view name, uint32_t value) = 0; + virtual void AddFieldInt32(std::wstring_view name, int32_t value, std::wstring_view unit = {}) = 0; + // Floats + virtual void AddFieldFloat(std::wstring_view name, float value, std::wstring_view unit = {}) = 0; + // Enums + virtual void AddFieldEnum(std::wstring_view name, uint32_t value, const EnumItem* enumItems) = 0; + virtual void AddFieldEnumSigned(std::wstring_view name, int32_t value, const EnumItem* enumItems) = 0; + virtual void AddEnumArray(std::wstring_view name, const uint32_t* values, size_t count, const EnumItem* enumItems) = 0; + virtual void AddFieldFlags(std::wstring_view name, uint32_t value, const EnumItem* enumItems) = 0; + // Binary data + virtual void AddFieldHexBytes(std::wstring_view name, const void* data, size_t byteCount) = 0; + // Custom types + virtual void AddFieldVendorId(std::wstring_view name, uint32_t value) = 0; + virtual void AddFieldSubsystemId(std::wstring_view name, uint32_t value) = 0; + virtual void AddFieldMicrosoftVersion(std::wstring_view name, uint64_t value) = 0; + virtual void AddFieldAMDVersion(std::wstring_view name, uint64_t value) = 0; + virtual void AddFieldNvidiaImplementationID(std::wstring_view name, uint32_t architectureId, uint32_t implementationId, const EnumItem* architecturePlusImplementationIDEnum) = 0; +}; + +ReportFormatter::Flags operator&(ReportFormatter::Flags a, ReportFormatter::Flags b); +ReportFormatter::Flags operator|(ReportFormatter::Flags a, ReportFormatter::Flags b); +bool operator||(bool a, ReportFormatter::Flags b); +bool operator&&(bool a, ReportFormatter::Flags b); +bool operator!(ReportFormatter::Flags a); + +class ReportScopeObject +{ +public: + ReportScopeObject(std::wstring_view name); + ~ReportScopeObject(); +}; + +class ReportScopeArray +{ +public: + ReportScopeArray(std::wstring_view name, ReportFormatter::ArraySuffix suffix = ReportFormatter::ArraySuffix::SquareBrackets); + ~ReportScopeArray(); +}; + +class ReportScopeArrayItem +{ +public: + ReportScopeArrayItem(); + ~ReportScopeArrayItem(); +}; + +class ReportScopeObjectConditional +{ +public: + ReportScopeObjectConditional(std::wstring_view name); + ReportScopeObjectConditional(bool enable, std::wstring_view name); + ~ReportScopeObjectConditional(); + void Enable(); +private: + std::wstring m_Name; + bool m_Enabled = false; +}; + +class ReportScopeArrayConditional +{ +public: + ReportScopeArrayConditional(std::wstring_view name, ReportFormatter::ArraySuffix suffix = ReportFormatter::ArraySuffix::SquareBrackets); + ReportScopeArrayConditional(bool enable, std::wstring_view name, ReportFormatter::ArraySuffix suffix = ReportFormatter::ArraySuffix::SquareBrackets); + ~ReportScopeArrayConditional(); + void Enable(); +private: + std::wstring m_Name; + ReportFormatter::ArraySuffix m_Suffix; + bool m_Enabled = false; +}; + +class ReportScopeArrayItemConditional +{ +public: + ReportScopeArrayItemConditional(); + ReportScopeArrayItemConditional(bool enable); + ~ReportScopeArrayItemConditional(); + void Enable(); +private: + bool m_Enabled = false; +}; + +bool IsOutputConsole(); +bool IsOutputJson(); +std::wstring_view OutputSpecificString(std::wstring_view consoleString, std::wstring_view jsonString); +std::string_view OutputSpecificString(std::string_view consoleString, std::string_view jsonString); diff --git a/Src/VulkanData.cpp b/Src/VulkanData.cpp index 6719577..3631a09 100644 --- a/Src/VulkanData.cpp +++ b/Src/VulkanData.cpp @@ -8,10 +8,9 @@ License: MIT For more information, see files README.md, LICENSE.txt. */ #include "VulkanData.hpp" -#include "Printing.hpp" #include "Utils.hpp" -#include "Json.hpp" #include "Enums.hpp" +#include "ReportFormatter/ReportFormatter.hpp" // Macro set by Cmake. #if USE_VULKAN @@ -196,32 +195,32 @@ void Vulkan_Initialize_RAII::PrintData(const DXGI_ADAPTER_DESC& adapterDesc) { const VkPhysicalDeviceProperties& props = propSet.properties2.properties; - ScopedStructRegion region(L"VkPhysicalDeviceProperties"); - Print_string(L"apiVersion", std::format(L"{}.{}.{}", + ReportScopeObject region(L"VkPhysicalDeviceProperties"); + ReportFormatter::GetInstance().AddFieldString(L"apiVersion", std::format(L"{}.{}.{}", VK_API_VERSION_MAJOR(props.apiVersion), VK_API_VERSION_MINOR(props.apiVersion), VK_API_VERSION_PATCH(props.apiVersion)).c_str()); - Print_uint32(L"driverVersion", props.driverVersion); - PrintVendorId(L"vendorID", props.vendorID); - Print_hex32(L"deviceID", props.deviceID); - PrintEnum(L"deviceType", props.deviceType, Enum_VkPhysicalDeviceType); - Print_string(L"deviceName", StrToWstr(props.deviceName, CP_UTF8).c_str()); + ReportFormatter::GetInstance().AddFieldUint32(L"driverVersion", props.driverVersion); + ReportFormatter::GetInstance().AddFieldVendorId(L"vendorID", props.vendorID); + ReportFormatter::GetInstance().AddFieldHex32(L"deviceID", props.deviceID); + ReportFormatter::GetInstance().AddFieldEnum(L"deviceType", props.deviceType, Enum_VkPhysicalDeviceType); + ReportFormatter::GetInstance().AddFieldString(L"deviceName", StrToWstr(props.deviceName, CP_UTF8).c_str()); } { const VkPhysicalDeviceIDProperties& IDProps = propSet.IDProperties; - ScopedStructRegion region(L"VkPhysicalDeviceIDProperties"); - PrintHexBytes(L"deviceUUID", IDProps.deviceUUID, VK_UUID_SIZE); - PrintHexBytes(L"driverUUID", IDProps.driverUUID, VK_UUID_SIZE); + ReportScopeObject region(L"VkPhysicalDeviceIDProperties"); + ReportFormatter::GetInstance().AddFieldHexBytes(L"deviceUUID", IDProps.deviceUUID, VK_UUID_SIZE); + ReportFormatter::GetInstance().AddFieldHexBytes(L"driverUUID", IDProps.driverUUID, VK_UUID_SIZE); if(IDProps.deviceLUIDValid) - PrintHexBytes(L"deviceLUID", IDProps.deviceLUID, VK_LUID_SIZE); + ReportFormatter::GetInstance().AddFieldHexBytes(L"deviceLUID", IDProps.deviceLUID, VK_LUID_SIZE); } if(g_ApiVersion >= VK_API_VERSION_1_2) { const VkPhysicalDeviceVulkan12Properties& vulkan12Props = propSet.vulkan12Properties; - ScopedStructRegion region(L"VkPhysicalDeviceVulkan12Properties"); - PrintEnum(L"driverID", vulkan12Props.driverID, Enum_VkDriverId); - Print_string(L"driverName", StrToWstr(vulkan12Props.driverName, CP_UTF8).c_str()); - Print_string(L"driverInfo", StrToWstr(vulkan12Props.driverInfo, CP_UTF8).c_str()); + ReportScopeObject region(L"VkPhysicalDeviceVulkan12Properties"); + ReportFormatter::GetInstance().AddFieldEnum(L"driverID", vulkan12Props.driverID, Enum_VkDriverId); + ReportFormatter::GetInstance().AddFieldString(L"driverName", StrToWstr(vulkan12Props.driverName, CP_UTF8).c_str()); + ReportFormatter::GetInstance().AddFieldString(L"driverInfo", StrToWstr(vulkan12Props.driverInfo, CP_UTF8).c_str()); } } diff --git a/Src/pch.hpp b/Src/pch.hpp index 2253968..209904c 100644 --- a/Src/pch.hpp +++ b/Src/pch.hpp @@ -40,6 +40,7 @@ For more information, see files README.md, LICENSE.txt. #include #include #include +#include #include #include From c11c72cd88f4b05c2a0570c6b3cda351ecc50c11 Mon Sep 17 00:00:00 2001 From: Dmytro Bulatov Date: Tue, 25 Feb 2025 03:23:29 +0900 Subject: [PATCH 2/6] Cleaned up usage repeated usage of report formatter --- Src/AgsData.cpp | 60 ++++---- Src/AmdDeviceInfoData.cpp | 32 ++-- Src/IntelData.cpp | 37 ++--- Src/Main.cpp | 297 ++++++++++++++++++++------------------ Src/NvApiData.cpp | 153 ++++++++++---------- Src/VulkanData.cpp | 25 ++-- 6 files changed, 319 insertions(+), 285 deletions(-) diff --git a/Src/AgsData.cpp b/Src/AgsData.cpp index 8f390d1..a61e190 100644 --- a/Src/AgsData.cpp +++ b/Src/AgsData.cpp @@ -113,22 +113,23 @@ void AGS_Initialize_RAII::PrintAgsDeviceData(const DeviceId& id) const AGSDeviceInfo& device = g_GpuInfo.devices[deviceIndex]; ReportScopeObject region(L"AGSDeviceInfo"); - ReportFormatter::GetInstance().AddFieldString(L"adapterString", StrToWstr(device.adapterString, CP_ACP).c_str()); - ReportFormatter::GetInstance().AddFieldEnum(L"asicFamily", device.asicFamily, Enum_AGSDeviceInfo_AsicFamily); - ReportFormatter::GetInstance().AddFieldBool(L"isAPU", device.isAPU); - ReportFormatter::GetInstance().AddFieldBool(L"isExternal", device.isExternal); - ReportFormatter::GetInstance().AddFieldVendorId(L"vendorId", (uint32_t)device.vendorId); - ReportFormatter::GetInstance().AddFieldHex32(L"deviceId", (uint32_t)device.deviceId); - ReportFormatter::GetInstance().AddFieldHex32(L"revisionId", (uint32_t)device.revisionId); - ReportFormatter::GetInstance().AddFieldInt32(L"numCUs", device.numCUs); - ReportFormatter::GetInstance().AddFieldInt32(L"numWGPs", device.numWGPs); - ReportFormatter::GetInstance().AddFieldInt32(L"numROPs", device.numROPs); - ReportFormatter::GetInstance().AddFieldInt32(L"coreClock", device.coreClock, L"MHz"); - ReportFormatter::GetInstance().AddFieldInt32(L"memoryClock", device.memoryClock, L"MHz"); - ReportFormatter::GetInstance().AddFieldInt32(L"memoryBandwidth", device.memoryBandwidth, L"MB/s"); - ReportFormatter::GetInstance().AddFieldFloat(L"teraFlops", device.teraFlops, L"TFLOPS"); - ReportFormatter::GetInstance().AddFieldSize(L"localMemoryInBytes", device.localMemoryInBytes); - ReportFormatter::GetInstance().AddFieldSize(L"sharedMemoryInBytes", device.sharedMemoryInBytes); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldString(L"adapterString", StrToWstr(device.adapterString, CP_ACP).c_str()); + formatter.AddFieldEnum(L"asicFamily", device.asicFamily, Enum_AGSDeviceInfo_AsicFamily); + formatter.AddFieldBool(L"isAPU", device.isAPU); + formatter.AddFieldBool(L"isExternal", device.isExternal); + formatter.AddFieldVendorId(L"vendorId", (uint32_t)device.vendorId); + formatter.AddFieldHex32(L"deviceId", (uint32_t)device.deviceId); + formatter.AddFieldHex32(L"revisionId", (uint32_t)device.revisionId); + formatter.AddFieldInt32(L"numCUs", device.numCUs); + formatter.AddFieldInt32(L"numWGPs", device.numWGPs); + formatter.AddFieldInt32(L"numROPs", device.numROPs); + formatter.AddFieldInt32(L"coreClock", device.coreClock, L"MHz"); + formatter.AddFieldInt32(L"memoryClock", device.memoryClock, L"MHz"); + formatter.AddFieldInt32(L"memoryBandwidth", device.memoryBandwidth, L"MB/s"); + formatter.AddFieldFloat(L"teraFlops", device.teraFlops, L"TFLOPS"); + formatter.AddFieldSize(L"localMemoryInBytes", device.localMemoryInBytes); + formatter.AddFieldSize(L"sharedMemoryInBytes", device.sharedMemoryInBytes); } ComPtr AGS_Initialize_RAII::CreateDeviceAndPrintData(IDXGIAdapter* adapter, D3D_FEATURE_LEVEL featureLevel) @@ -152,19 +153,20 @@ ComPtr AGS_Initialize_RAII::CreateDeviceAndPrintData(IDXGIAdapter* g_DeviceCreatedWithAgs = true; ReportScopeObject region(L"AGSDX12ReturnedParams::ExtensionsSupported"); - ReportFormatter::GetInstance().AddFieldBool(L"intrinsics16", returnedParams.extensionsSupported.intrinsics16); - ReportFormatter::GetInstance().AddFieldBool(L"intrinsics17", returnedParams.extensionsSupported.intrinsics17); - ReportFormatter::GetInstance().AddFieldBool(L"userMarkers", returnedParams.extensionsSupported.userMarkers); - ReportFormatter::GetInstance().AddFieldBool(L"appRegistration", returnedParams.extensionsSupported.appRegistration); - ReportFormatter::GetInstance().AddFieldBool(L"UAVBindSlot", returnedParams.extensionsSupported.UAVBindSlot); - ReportFormatter::GetInstance().AddFieldBool(L"intrinsics19", returnedParams.extensionsSupported.intrinsics19); - ReportFormatter::GetInstance().AddFieldBool(L"baseVertex", returnedParams.extensionsSupported.baseVertex); - ReportFormatter::GetInstance().AddFieldBool(L"baseInstance", returnedParams.extensionsSupported.baseInstance); - ReportFormatter::GetInstance().AddFieldBool(L"getWaveSize", returnedParams.extensionsSupported.getWaveSize); - ReportFormatter::GetInstance().AddFieldBool(L"floatConversion", returnedParams.extensionsSupported.floatConversion); - ReportFormatter::GetInstance().AddFieldBool(L"readLaneAt", returnedParams.extensionsSupported.readLaneAt); - ReportFormatter::GetInstance().AddFieldBool(L"rayHitToken", returnedParams.extensionsSupported.rayHitToken); - ReportFormatter::GetInstance().AddFieldBool(L"shaderClock", returnedParams.extensionsSupported.shaderClock); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldBool(L"intrinsics16", returnedParams.extensionsSupported.intrinsics16); + formatter.AddFieldBool(L"intrinsics17", returnedParams.extensionsSupported.intrinsics17); + formatter.AddFieldBool(L"userMarkers", returnedParams.extensionsSupported.userMarkers); + formatter.AddFieldBool(L"appRegistration", returnedParams.extensionsSupported.appRegistration); + formatter.AddFieldBool(L"UAVBindSlot", returnedParams.extensionsSupported.UAVBindSlot); + formatter.AddFieldBool(L"intrinsics19", returnedParams.extensionsSupported.intrinsics19); + formatter.AddFieldBool(L"baseVertex", returnedParams.extensionsSupported.baseVertex); + formatter.AddFieldBool(L"baseInstance", returnedParams.extensionsSupported.baseInstance); + formatter.AddFieldBool(L"getWaveSize", returnedParams.extensionsSupported.getWaveSize); + formatter.AddFieldBool(L"floatConversion", returnedParams.extensionsSupported.floatConversion); + formatter.AddFieldBool(L"readLaneAt", returnedParams.extensionsSupported.readLaneAt); + formatter.AddFieldBool(L"rayHitToken", returnedParams.extensionsSupported.rayHitToken); + formatter.AddFieldBool(L"shaderClock", returnedParams.extensionsSupported.shaderClock); return device; } diff --git a/Src/AmdDeviceInfoData.cpp b/Src/AmdDeviceInfoData.cpp index 940b064..3b3de2c 100644 --- a/Src/AmdDeviceInfoData.cpp +++ b/Src/AmdDeviceInfoData.cpp @@ -124,13 +124,15 @@ void AmdDeviceInfo_Initialize_RAII::PrintDeviceData(const DeviceId& id) if(!cardInfo) return; + ReportFormatter& formatter = ReportFormatter::GetInstance(); + { - ReportScopeObject region{L"AMD GDT_GfxCardInfo"}; - ReportFormatter::GetInstance().AddFieldEnum(L"asicType", cardInfo->m_asicType, Enum_GDT_HW_ASIC_TYPE); - ReportFormatter::GetInstance().AddFieldEnum(L"generation", cardInfo->m_generation, Enum_GDT_HW_GENERATION); - ReportFormatter::GetInstance().AddFieldBool(L"APU", cardInfo->m_bAPU ? TRUE : FALSE); - ReportFormatter::GetInstance().AddFieldString(L"CALName", StrToWstr(cardInfo->m_szCALName, CP_UTF8).c_str()); - ReportFormatter::GetInstance().AddFieldString(L"MarketingName", StrToWstr(cardInfo->m_szMarketingName, CP_UTF8).c_str()); + ReportScopeObject region{ L"AMD GDT_GfxCardInfo" }; + formatter.AddFieldEnum(L"asicType", cardInfo->m_asicType, Enum_GDT_HW_ASIC_TYPE); + formatter.AddFieldEnum(L"generation", cardInfo->m_generation, Enum_GDT_HW_GENERATION); + formatter.AddFieldBool(L"APU", cardInfo->m_bAPU ? TRUE : FALSE); + formatter.AddFieldString(L"CALName", StrToWstr(cardInfo->m_szCALName, CP_UTF8).c_str()); + formatter.AddFieldString(L"MarketingName", StrToWstr(cardInfo->m_szMarketingName, CP_UTF8).c_str()); } if(cardInfo->m_asicType >= 0 && cardInfo->m_asicType < gs_deviceInfoSize) @@ -139,15 +141,15 @@ void AmdDeviceInfo_Initialize_RAII::PrintDeviceData(const DeviceId& id) if(devInfo.m_deviceInfoValid) { ReportScopeObject region(L"AMD GDT_DeviceInfo"); - ReportFormatter::GetInstance().AddFieldUint64(L"NumShaderEngines", devInfo.m_nNumShaderEngines); // Number of shader engines. - ReportFormatter::GetInstance().AddFieldUint64(L"MaxWavePerSIMD", devInfo.m_nMaxWavePerSIMD); // Number of wave slots per SIMD. - ReportFormatter::GetInstance().AddFieldUint64(L"ClocksPrim", devInfo.m_suClocksPrim); // Number of clocks it takes to process a primitive. - ReportFormatter::GetInstance().AddFieldUint64(L"NumSQMaxCounters", devInfo.m_nNumSQMaxCounters); // Max number of SQ counters. - ReportFormatter::GetInstance().AddFieldUint64(L"NumPrimPipes", devInfo.m_nNumPrimPipes); // Number of primitive pipes. - ReportFormatter::GetInstance().AddFieldUint64(L"WaveSize", devInfo.m_nWaveSize); // Wavefront size. - ReportFormatter::GetInstance().AddFieldUint64(L"NumSHPerSE", devInfo.m_nNumSHPerSE); // Number of shader array per Shader Engine. - ReportFormatter::GetInstance().AddFieldUint64(L"NumCUPerSH", devInfo.m_nNumCUPerSH); // Number of compute unit per Shader Array. - ReportFormatter::GetInstance().AddFieldUint64(L"NumSIMDPerCU", devInfo.m_nNumSIMDPerCU); // Number of SIMDs per Compute unit. + formatter.AddFieldUint64(L"NumShaderEngines", devInfo.m_nNumShaderEngines); // Number of shader engines. + formatter.AddFieldUint64(L"MaxWavePerSIMD", devInfo.m_nMaxWavePerSIMD); // Number of wave slots per SIMD. + formatter.AddFieldUint64(L"ClocksPrim", devInfo.m_suClocksPrim); // Number of clocks it takes to process a primitive. + formatter.AddFieldUint64(L"NumSQMaxCounters", devInfo.m_nNumSQMaxCounters); // Max number of SQ counters. + formatter.AddFieldUint64(L"NumPrimPipes", devInfo.m_nNumPrimPipes); // Number of primitive pipes. + formatter.AddFieldUint64(L"WaveSize", devInfo.m_nWaveSize); // Wavefront size. + formatter.AddFieldUint64(L"NumSHPerSE", devInfo.m_nNumSHPerSE); // Number of shader array per Shader Engine. + formatter.AddFieldUint64(L"NumCUPerSH", devInfo.m_nNumCUPerSH); // Number of compute unit per Shader Array. + formatter.AddFieldUint64(L"NumSIMDPerCU", devInfo.m_nNumSIMDPerCU); // Number of SIMDs per Compute unit. } } } diff --git a/Src/IntelData.cpp b/Src/IntelData.cpp index 280fc88..a406911 100644 --- a/Src/IntelData.cpp +++ b/Src/IntelData.cpp @@ -1995,28 +1995,29 @@ void PrintAdapterData(IDXGIAdapter* adapter) return; ReportScopeObject region(L"Intel GPUDetect::GPUData"); - ReportFormatter::GetInstance().AddFieldVendorId(L"VendorId", gpuData.vendorID); - ReportFormatter::GetInstance().AddFieldHex32(L"deviceID", gpuData.deviceID); - ReportFormatter::GetInstance().AddFieldBool(L"isUMAArchitecture", gpuData.isUMAArchitecture ? TRUE : FALSE); - ReportFormatter::GetInstance().AddFieldSize(L"videoMemory", gpuData.videoMemory); - ReportFormatter::GetInstance().AddFieldString(L"description", gpuData.description); - ReportFormatter::GetInstance().AddFieldHex32(L"extensionVersion", gpuData.extensionVersion); - ReportFormatter::GetInstance().AddFieldBool(L"intelExtensionAvailability", gpuData.intelExtensionAvailability ? TRUE : FALSE); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldVendorId(L"VendorId", gpuData.vendorID); + formatter.AddFieldHex32(L"deviceID", gpuData.deviceID); + formatter.AddFieldBool(L"isUMAArchitecture", gpuData.isUMAArchitecture ? TRUE : FALSE); + formatter.AddFieldSize(L"videoMemory", gpuData.videoMemory); + formatter.AddFieldString(L"description", gpuData.description); + formatter.AddFieldHex32(L"extensionVersion", gpuData.extensionVersion); + formatter.AddFieldBool(L"intelExtensionAvailability", gpuData.intelExtensionAvailability ? TRUE : FALSE); r = GPUDetect::InitDxDriverVersion(&gpuData); if(r == EXIT_SUCCESS && gpuData.d3dRegistryDataAvailability) { char driverVersionStr[19] = {}; GPUDetect::GetDriverVersionAsCString(&gpuData, driverVersionStr, _countof(driverVersionStr)); - ReportFormatter::GetInstance().AddFieldString(L"dxDriverVersion", StrToWstr(driverVersionStr, CP_ACP).c_str()); - ReportFormatter::GetInstance().AddFieldUint32(L"driverInfo.driverReleaseRevision", gpuData.driverInfo.driverReleaseRevision); - ReportFormatter::GetInstance().AddFieldUint32(L"driverInfo.driverBuildNumber", gpuData.driverInfo.driverBuildNumber); + formatter.AddFieldString(L"dxDriverVersion", StrToWstr(driverVersionStr, CP_ACP).c_str()); + formatter.AddFieldUint32(L"driverInfo.driverReleaseRevision", gpuData.driverInfo.driverReleaseRevision); + formatter.AddFieldUint32(L"driverInfo.driverBuildNumber", gpuData.driverInfo.driverBuildNumber); } if(gpuData.vendorID == GPUDetect::INTEL_VENDOR_ID) { const GPUDetect::PresetLevel presetLevel = GPUDetect::GetDefaultFidelityPreset(&gpuData); - ReportFormatter::GetInstance().AddFieldEnum(L"DefaultFidelityPreset", (uint32_t)presetLevel, GPUDetect::Enum_PresetLevel); + formatter.AddFieldEnum(L"DefaultFidelityPreset", (uint32_t)presetLevel, GPUDetect::Enum_PresetLevel); r = GPUDetect::InitCounterInfo(&gpuData, device.Get()); if(r == EXIT_SUCCESS) @@ -2024,24 +2025,24 @@ void PrintAdapterData(IDXGIAdapter* adapter) string architectureStr = GPUDetect::GetIntelGPUArchitectureString(gpuData.architecture); if(architectureStr == "Unknown") architectureStr = std::format("Unknown ({})", (uint32_t)gpuData.architecture); - ReportFormatter::GetInstance().AddFieldString(L"GPUArchitecture", StrToWstr(architectureStr.c_str(), CP_ACP).c_str()); + formatter.AddFieldString(L"GPUArchitecture", StrToWstr(architectureStr.c_str(), CP_ACP).c_str()); const GPUDetect::IntelGraphicsGeneration generation = GPUDetect::GetIntelGraphicsGeneration(gpuData.architecture); string generationStr = GPUDetect::GetIntelGraphicsGenerationString(generation); if(generationStr == "Unknown") generationStr = std::format("Unknown ({})", (uint32_t)generation); - ReportFormatter::GetInstance().AddFieldString(L"GraphicsGeneration", StrToWstr(generationStr.c_str(), CP_ACP).c_str()); + formatter.AddFieldString(L"GraphicsGeneration", StrToWstr(generationStr.c_str(), CP_ACP).c_str()); if(gpuData.advancedCounterDataAvailability) { - ReportFormatter::GetInstance().AddFieldUint32(L"euCount", gpuData.euCount); - ReportFormatter::GetInstance().AddFieldUint32(L"packageTDP", gpuData.packageTDP, L"W"); - ReportFormatter::GetInstance().AddFieldUint32(L"maxFillRate", gpuData.maxFillRate, L"pixels/clock"); + formatter.AddFieldUint32(L"euCount", gpuData.euCount); + formatter.AddFieldUint32(L"packageTDP", gpuData.packageTDP, L"W"); + formatter.AddFieldUint32(L"maxFillRate", gpuData.maxFillRate, L"pixels/clock"); } - ReportFormatter::GetInstance().AddFieldUint32(L"maxFrequency", gpuData.maxFrequency, L"MHz"); - ReportFormatter::GetInstance().AddFieldUint32(L"minFrequency", gpuData.minFrequency, L"MHz"); + formatter.AddFieldUint32(L"maxFrequency", gpuData.maxFrequency, L"MHz"); + formatter.AddFieldUint32(L"minFrequency", gpuData.minFrequency, L"MHz"); } } } diff --git a/Src/Main.cpp b/Src/Main.cpp index 5e40257..16fd632 100644 --- a/Src/Main.cpp +++ b/Src/Main.cpp @@ -115,40 +115,43 @@ static wstring LuidToStr(LUID value) static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS(const D3D12_FEATURE_DATA_D3D12_OPTIONS& options) { ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS"); - ReportFormatter::GetInstance().AddFieldBool(L"DoublePrecisionFloatShaderOps", options.DoublePrecisionFloatShaderOps); - ReportFormatter::GetInstance().AddFieldBool(L"OutputMergerLogicOp", options.OutputMergerLogicOp); - ReportFormatter::GetInstance().AddFieldEnum(L"MinPrecisionSupport", options.MinPrecisionSupport, Enum_D3D12_SHADER_MIN_PRECISION_SUPPORT); - ReportFormatter::GetInstance().AddFieldEnum(L"TiledResourcesTier", options.TiledResourcesTier, Enum_D3D12_TILED_RESOURCES_TIER); - ReportFormatter::GetInstance().AddFieldEnum(L"ResourceBindingTier", options.ResourceBindingTier, Enum_D3D12_RESOURCE_BINDING_TIER); - ReportFormatter::GetInstance().AddFieldBool(L"PSSpecifiedStencilRefSupported", options.PSSpecifiedStencilRefSupported); - ReportFormatter::GetInstance().AddFieldBool(L"TypedUAVLoadAdditionalFormats", options.TypedUAVLoadAdditionalFormats); - ReportFormatter::GetInstance().AddFieldBool(L"ROVsSupported", options.ROVsSupported); - ReportFormatter::GetInstance().AddFieldEnum(L"ConservativeRasterizationTier", options.ConservativeRasterizationTier, Enum_D3D12_CONSERVATIVE_RASTERIZATION_TIER); - ReportFormatter::GetInstance().AddFieldUint32(L"MaxGPUVirtualAddressBitsPerResource", options.MaxGPUVirtualAddressBitsPerResource); - ReportFormatter::GetInstance().AddFieldBool(L"StandardSwizzle64KBSupported", options.StandardSwizzle64KBSupported); - ReportFormatter::GetInstance().AddFieldEnum(L"CrossNodeSharingTier", options.CrossNodeSharingTier, Enum_D3D12_CROSS_NODE_SHARING_TIER); - ReportFormatter::GetInstance().AddFieldBool(L"CrossAdapterRowMajorTextureSupported", options.CrossAdapterRowMajorTextureSupported); - ReportFormatter::GetInstance().AddFieldBool(L"VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation", options.VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation); - ReportFormatter::GetInstance().AddFieldEnum(L"ResourceHeapTier", options.ResourceHeapTier, Enum_D3D12_RESOURCE_HEAP_TIER); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldBool(L"DoublePrecisionFloatShaderOps", options.DoublePrecisionFloatShaderOps); + formatter.AddFieldBool(L"OutputMergerLogicOp", options.OutputMergerLogicOp); + formatter.AddFieldEnum(L"MinPrecisionSupport", options.MinPrecisionSupport, Enum_D3D12_SHADER_MIN_PRECISION_SUPPORT); + formatter.AddFieldEnum(L"TiledResourcesTier", options.TiledResourcesTier, Enum_D3D12_TILED_RESOURCES_TIER); + formatter.AddFieldEnum(L"ResourceBindingTier", options.ResourceBindingTier, Enum_D3D12_RESOURCE_BINDING_TIER); + formatter.AddFieldBool(L"PSSpecifiedStencilRefSupported", options.PSSpecifiedStencilRefSupported); + formatter.AddFieldBool(L"TypedUAVLoadAdditionalFormats", options.TypedUAVLoadAdditionalFormats); + formatter.AddFieldBool(L"ROVsSupported", options.ROVsSupported); + formatter.AddFieldEnum(L"ConservativeRasterizationTier", options.ConservativeRasterizationTier, Enum_D3D12_CONSERVATIVE_RASTERIZATION_TIER); + formatter.AddFieldUint32(L"MaxGPUVirtualAddressBitsPerResource", options.MaxGPUVirtualAddressBitsPerResource); + formatter.AddFieldBool(L"StandardSwizzle64KBSupported", options.StandardSwizzle64KBSupported); + formatter.AddFieldEnum(L"CrossNodeSharingTier", options.CrossNodeSharingTier, Enum_D3D12_CROSS_NODE_SHARING_TIER); + formatter.AddFieldBool(L"CrossAdapterRowMajorTextureSupported", options.CrossAdapterRowMajorTextureSupported); + formatter.AddFieldBool(L"VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation", options.VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation); + formatter.AddFieldEnum(L"ResourceHeapTier", options.ResourceHeapTier, Enum_D3D12_RESOURCE_HEAP_TIER); } static void Print_D3D12_FEATURE_DATA_ARCHITECTURE(const D3D12_FEATURE_DATA_ARCHITECTURE& architecture) { ReportScopeObject scope(L"D3D12_FEATURE_DATA_ARCHITECTURE"); - ReportFormatter::GetInstance().AddFieldUint32(L"NodeIndex", architecture.NodeIndex); - ReportFormatter::GetInstance().AddFieldBool(L"TileBasedRenderer", architecture.TileBasedRenderer); - ReportFormatter::GetInstance().AddFieldBool(L"UMA", architecture.UMA); - ReportFormatter::GetInstance().AddFieldBool(L"CacheCoherentUMA", architecture.CacheCoherentUMA); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldUint32(L"NodeIndex", architecture.NodeIndex); + formatter.AddFieldBool(L"TileBasedRenderer", architecture.TileBasedRenderer); + formatter.AddFieldBool(L"UMA", architecture.UMA); + formatter.AddFieldBool(L"CacheCoherentUMA", architecture.CacheCoherentUMA); } static void Print_D3D12_FEATURE_DATA_ARCHITECTURE1(const D3D12_FEATURE_DATA_ARCHITECTURE1& architecture1) { ReportScopeObject scope(L"D3D12_FEATURE_DATA_ARCHITECTURE1"); - ReportFormatter::GetInstance().AddFieldUint32(L"NodeIndex", architecture1.NodeIndex); - ReportFormatter::GetInstance().AddFieldBool(L"TileBasedRenderer", architecture1.TileBasedRenderer); - ReportFormatter::GetInstance().AddFieldBool(L"UMA", architecture1.UMA); - ReportFormatter::GetInstance().AddFieldBool(L"CacheCoherentUMA", architecture1.CacheCoherentUMA); - ReportFormatter::GetInstance().AddFieldBool(L"IsolatedMMU", architecture1.IsolatedMMU); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldUint32(L"NodeIndex", architecture1.NodeIndex); + formatter.AddFieldBool(L"TileBasedRenderer", architecture1.TileBasedRenderer); + formatter.AddFieldBool(L"UMA", architecture1.UMA); + formatter.AddFieldBool(L"CacheCoherentUMA", architecture1.CacheCoherentUMA); + formatter.AddFieldBool(L"IsolatedMMU", architecture1.IsolatedMMU); } static void Print_D3D12_FEATURE_DATA_FEATURE_LEVELS(const D3D12_FEATURE_DATA_FEATURE_LEVELS& featureLevels) @@ -178,12 +181,13 @@ static void Print_D3D12_FEATURE_DATA_SHADER_MODEL(const D3D12_FEATURE_DATA_SHADE static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS1(const D3D12_FEATURE_DATA_D3D12_OPTIONS1& options1) { ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS1"); - ReportFormatter::GetInstance().AddFieldBool(L"WaveOps", options1.WaveOps); - ReportFormatter::GetInstance().AddFieldUint32(L"WaveLaneCountMin", options1.WaveLaneCountMin); - ReportFormatter::GetInstance().AddFieldUint32(L"WaveLaneCountMax", options1.WaveLaneCountMax); - ReportFormatter::GetInstance().AddFieldUint32(L"TotalLaneCount", options1.TotalLaneCount); - ReportFormatter::GetInstance().AddFieldBool(L"ExpandedComputeResourceStates", options1.ExpandedComputeResourceStates); - ReportFormatter::GetInstance().AddFieldBool(L"Int64ShaderOps", options1.Int64ShaderOps); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldBool(L"WaveOps", options1.WaveOps); + formatter.AddFieldUint32(L"WaveLaneCountMin", options1.WaveLaneCountMin); + formatter.AddFieldUint32(L"WaveLaneCountMax", options1.WaveLaneCountMax); + formatter.AddFieldUint32(L"TotalLaneCount", options1.TotalLaneCount); + formatter.AddFieldBool(L"ExpandedComputeResourceStates", options1.ExpandedComputeResourceStates); + formatter.AddFieldBool(L"Int64ShaderOps", options1.Int64ShaderOps); } static void Print_D3D12_FEATURE_DATA_ROOT_SIGNATURE(const D3D12_FEATURE_DATA_ROOT_SIGNATURE& rootSignature) @@ -208,15 +212,16 @@ static void Print_D3D12_FEATURE_DATA_SHADER_CACHE(const D3D12_FEATURE_DATA_SHADE static void Print_D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY(const std::array& commandQueuePriority) { ReportScopeObject scope(L"D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY"); - ReportFormatter::GetInstance().AddFieldBool(L"TYPE_DIRECT.PRIORITY_NORMAL.PriorityForTypeIsSupported", commandQueuePriority[0]); - ReportFormatter::GetInstance().AddFieldBool(L"TYPE_DIRECT.PRIORITY_HIGH.PriorityForTypeIsSupported", commandQueuePriority[1]); - ReportFormatter::GetInstance().AddFieldBool(L"TYPE_DIRECT.PRIORITY_GLOBAL_REALTIME.PriorityForTypeIsSupported", commandQueuePriority[2]); - ReportFormatter::GetInstance().AddFieldBool(L"TYPE_COMPUTE.PRIORITY_NORMAL.PriorityForTypeIsSupported", commandQueuePriority[3]); - ReportFormatter::GetInstance().AddFieldBool(L"TYPE_COMPUTE.PRIORITY_HIGH.PriorityForTypeIsSupported", commandQueuePriority[4]); - ReportFormatter::GetInstance().AddFieldBool(L"TYPE_COMPUTE.PRIORITY_GLOBAL_REALTIME.PriorityForTypeIsSupported", commandQueuePriority[5]); - ReportFormatter::GetInstance().AddFieldBool(L"TYPE_COPY.PRIORITY_NORMAL.PriorityForTypeIsSupported", commandQueuePriority[6]); - ReportFormatter::GetInstance().AddFieldBool(L"TYPE_COPY.PRIORITY_HIGH.PriorityForTypeIsSupported", commandQueuePriority[7]); - ReportFormatter::GetInstance().AddFieldBool(L"TYPE_COPY.PRIORITY_GLOBAL_REALTIME.PriorityForTypeIsSupported", commandQueuePriority[8]); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldBool(L"TYPE_DIRECT.PRIORITY_NORMAL.PriorityForTypeIsSupported", commandQueuePriority[0]); + formatter.AddFieldBool(L"TYPE_DIRECT.PRIORITY_HIGH.PriorityForTypeIsSupported", commandQueuePriority[1]); + formatter.AddFieldBool(L"TYPE_DIRECT.PRIORITY_GLOBAL_REALTIME.PriorityForTypeIsSupported", commandQueuePriority[2]); + formatter.AddFieldBool(L"TYPE_COMPUTE.PRIORITY_NORMAL.PriorityForTypeIsSupported", commandQueuePriority[3]); + formatter.AddFieldBool(L"TYPE_COMPUTE.PRIORITY_HIGH.PriorityForTypeIsSupported", commandQueuePriority[4]); + formatter.AddFieldBool(L"TYPE_COMPUTE.PRIORITY_GLOBAL_REALTIME.PriorityForTypeIsSupported", commandQueuePriority[5]); + formatter.AddFieldBool(L"TYPE_COPY.PRIORITY_NORMAL.PriorityForTypeIsSupported", commandQueuePriority[6]); + formatter.AddFieldBool(L"TYPE_COPY.PRIORITY_HIGH.PriorityForTypeIsSupported", commandQueuePriority[7]); + formatter.AddFieldBool(L"TYPE_COPY.PRIORITY_GLOBAL_REALTIME.PriorityForTypeIsSupported", commandQueuePriority[8]); } static void Print_D3D12_FEATURE_DATA_SERIALIZATION(const D3D12_FEATURE_DATA_SERIALIZATION& serialization) @@ -255,37 +260,41 @@ static void Print_D3D12_FEATURE_DATA_APPLICATION_SPECIFIC_DRIVER_STATE(const D3D static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS3(const D3D12_FEATURE_DATA_D3D12_OPTIONS3& options3) { ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS3"); - ReportFormatter::GetInstance().AddFieldBool(L"CopyQueueTimestampQueriesSupported", options3.CopyQueueTimestampQueriesSupported); - ReportFormatter::GetInstance().AddFieldBool(L"CastingFullyTypedFormatSupported", options3.CastingFullyTypedFormatSupported); - ReportFormatter::GetInstance().AddFieldFlags(L"WriteBufferImmediateSupportFlags", options3.WriteBufferImmediateSupportFlags, Enum_D3D12_COMMAND_LIST_SUPPORT_FLAGS); - ReportFormatter::GetInstance().AddFieldEnum(L"ViewInstancingTier", options3.ViewInstancingTier, Enum_D3D12_VIEW_INSTANCING_TIER); - ReportFormatter::GetInstance().AddFieldBool(L"BarycentricsSupported", options3.BarycentricsSupported); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldBool(L"CopyQueueTimestampQueriesSupported", options3.CopyQueueTimestampQueriesSupported); + formatter.AddFieldBool(L"CastingFullyTypedFormatSupported", options3.CastingFullyTypedFormatSupported); + formatter.AddFieldFlags(L"WriteBufferImmediateSupportFlags", options3.WriteBufferImmediateSupportFlags, Enum_D3D12_COMMAND_LIST_SUPPORT_FLAGS); + formatter.AddFieldEnum(L"ViewInstancingTier", options3.ViewInstancingTier, Enum_D3D12_VIEW_INSTANCING_TIER); + formatter.AddFieldBool(L"BarycentricsSupported", options3.BarycentricsSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS4(const D3D12_FEATURE_DATA_D3D12_OPTIONS4& options4) { ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS4"); - ReportFormatter::GetInstance().AddFieldBool(L"MSAA64KBAlignedTextureSupported", options4.MSAA64KBAlignedTextureSupported); - ReportFormatter::GetInstance().AddFieldEnum(L"SharedResourceCompatibilityTier", options4.SharedResourceCompatibilityTier, Enum_D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER); - ReportFormatter::GetInstance().AddFieldBool(L"Native16BitShaderOpsSupported", options4.Native16BitShaderOpsSupported); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldBool(L"MSAA64KBAlignedTextureSupported", options4.MSAA64KBAlignedTextureSupported); + formatter.AddFieldEnum(L"SharedResourceCompatibilityTier", options4.SharedResourceCompatibilityTier, Enum_D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER); + formatter.AddFieldBool(L"Native16BitShaderOpsSupported", options4.Native16BitShaderOpsSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS5(const D3D12_FEATURE_DATA_D3D12_OPTIONS5& options5) { ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS5"); - ReportFormatter::GetInstance().AddFieldBool(L"SRVOnlyTiledResourceTier3", options5.SRVOnlyTiledResourceTier3); - ReportFormatter::GetInstance().AddFieldEnum(L"RenderPassesTier", options5.RenderPassesTier, Enum_D3D12_RENDER_PASS_TIER); - ReportFormatter::GetInstance().AddFieldEnum(L"RaytracingTier", options5.RaytracingTier, Enum_D3D12_RAYTRACING_TIER); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldBool(L"SRVOnlyTiledResourceTier3", options5.SRVOnlyTiledResourceTier3); + formatter.AddFieldEnum(L"RenderPassesTier", options5.RenderPassesTier, Enum_D3D12_RENDER_PASS_TIER); + formatter.AddFieldEnum(L"RaytracingTier", options5.RaytracingTier, Enum_D3D12_RAYTRACING_TIER); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS6(const D3D12_FEATURE_DATA_D3D12_OPTIONS6& o) { ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS6"); - ReportFormatter::GetInstance().AddFieldBool(L"AdditionalShadingRatesSupported", o.AdditionalShadingRatesSupported); - ReportFormatter::GetInstance().AddFieldBool(L"PerPrimitiveShadingRateSupportedWithViewportIndexing", o.PerPrimitiveShadingRateSupportedWithViewportIndexing); - ReportFormatter::GetInstance().AddFieldEnum(L"VariableShadingRateTier", o.VariableShadingRateTier, Enum_D3D12_VARIABLE_SHADING_RATE_TIER); - ReportFormatter::GetInstance().AddFieldUint32(L"ShadingRateImageTileSize", o.ShadingRateImageTileSize); - ReportFormatter::GetInstance().AddFieldBool(L"BackgroundProcessingSupported", o.BackgroundProcessingSupported); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldBool(L"AdditionalShadingRatesSupported", o.AdditionalShadingRatesSupported); + formatter.AddFieldBool(L"PerPrimitiveShadingRateSupportedWithViewportIndexing", o.PerPrimitiveShadingRateSupportedWithViewportIndexing); + formatter.AddFieldEnum(L"VariableShadingRateTier", o.VariableShadingRateTier, Enum_D3D12_VARIABLE_SHADING_RATE_TIER); + formatter.AddFieldUint32(L"ShadingRateImageTileSize", o.ShadingRateImageTileSize); + formatter.AddFieldBool(L"BackgroundProcessingSupported", o.BackgroundProcessingSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS7(const D3D12_FEATURE_DATA_D3D12_OPTIONS7& o) @@ -304,12 +313,13 @@ static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS8(const D3D12_FEATURE_DATA_D3D static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS9(const D3D12_FEATURE_DATA_D3D12_OPTIONS9& o) { ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS9"); - ReportFormatter::GetInstance().AddFieldBool(L"MeshShaderPipelineStatsSupported", o.MeshShaderPipelineStatsSupported); - ReportFormatter::GetInstance().AddFieldBool(L"MeshShaderSupportsFullRangeRenderTargetArrayIndex", o.MeshShaderSupportsFullRangeRenderTargetArrayIndex); - ReportFormatter::GetInstance().AddFieldBool(L"AtomicInt64OnTypedResourceSupported", o.AtomicInt64OnTypedResourceSupported); - ReportFormatter::GetInstance().AddFieldBool(L"AtomicInt64OnGroupSharedSupported", o.AtomicInt64OnGroupSharedSupported); - ReportFormatter::GetInstance().AddFieldBool(L"DerivativesInMeshAndAmplificationShadersSupported", o.DerivativesInMeshAndAmplificationShadersSupported); - ReportFormatter::GetInstance().AddFieldEnum(L"WaveMMATier", o.WaveMMATier, Enum_D3D12_WAVE_MMA_TIER); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldBool(L"MeshShaderPipelineStatsSupported", o.MeshShaderPipelineStatsSupported); + formatter.AddFieldBool(L"MeshShaderSupportsFullRangeRenderTargetArrayIndex", o.MeshShaderSupportsFullRangeRenderTargetArrayIndex); + formatter.AddFieldBool(L"AtomicInt64OnTypedResourceSupported", o.AtomicInt64OnTypedResourceSupported); + formatter.AddFieldBool(L"AtomicInt64OnGroupSharedSupported", o.AtomicInt64OnGroupSharedSupported); + formatter.AddFieldBool(L"DerivativesInMeshAndAmplificationShadersSupported", o.DerivativesInMeshAndAmplificationShadersSupported); + formatter.AddFieldEnum(L"WaveMMATier", o.WaveMMATier, Enum_D3D12_WAVE_MMA_TIER); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS10(const D3D12_FEATURE_DATA_D3D12_OPTIONS10& o) @@ -328,28 +338,31 @@ static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS11(const D3D12_FEATURE_DATA_D3 static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS12(const D3D12_FEATURE_DATA_D3D12_OPTIONS12& o) { ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS12"); - ReportFormatter::GetInstance().AddFieldEnumSigned(L"MSPrimitivesPipelineStatisticIncludesCulledPrimitives", o.MSPrimitivesPipelineStatisticIncludesCulledPrimitives, Enum_D3D12_TRI_STATE); - ReportFormatter::GetInstance().AddFieldBool(L"EnhancedBarriersSupported", o.EnhancedBarriersSupported); - ReportFormatter::GetInstance().AddFieldBool(L"RelaxedFormatCastingSupported", o.RelaxedFormatCastingSupported); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldEnumSigned(L"MSPrimitivesPipelineStatisticIncludesCulledPrimitives", o.MSPrimitivesPipelineStatisticIncludesCulledPrimitives, Enum_D3D12_TRI_STATE); + formatter.AddFieldBool(L"EnhancedBarriersSupported", o.EnhancedBarriersSupported); + formatter.AddFieldBool(L"RelaxedFormatCastingSupported", o.RelaxedFormatCastingSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS13(const D3D12_FEATURE_DATA_D3D12_OPTIONS13& o) { ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS13"); - ReportFormatter::GetInstance().AddFieldBool(L"UnrestrictedBufferTextureCopyPitchSupported", o.UnrestrictedBufferTextureCopyPitchSupported); - ReportFormatter::GetInstance().AddFieldBool(L"UnrestrictedVertexElementAlignmentSupported", o.UnrestrictedVertexElementAlignmentSupported); - ReportFormatter::GetInstance().AddFieldBool(L"InvertedViewportHeightFlipsYSupported", o.InvertedViewportHeightFlipsYSupported); - ReportFormatter::GetInstance().AddFieldBool(L"InvertedViewportDepthFlipsZSupported", o.InvertedViewportDepthFlipsZSupported); - ReportFormatter::GetInstance().AddFieldBool(L"TextureCopyBetweenDimensionsSupported", o.TextureCopyBetweenDimensionsSupported); - ReportFormatter::GetInstance().AddFieldBool(L"AlphaBlendFactorSupported", o.AlphaBlendFactorSupported); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldBool(L"UnrestrictedBufferTextureCopyPitchSupported", o.UnrestrictedBufferTextureCopyPitchSupported); + formatter.AddFieldBool(L"UnrestrictedVertexElementAlignmentSupported", o.UnrestrictedVertexElementAlignmentSupported); + formatter.AddFieldBool(L"InvertedViewportHeightFlipsYSupported", o.InvertedViewportHeightFlipsYSupported); + formatter.AddFieldBool(L"InvertedViewportDepthFlipsZSupported", o.InvertedViewportDepthFlipsZSupported); + formatter.AddFieldBool(L"TextureCopyBetweenDimensionsSupported", o.TextureCopyBetweenDimensionsSupported); + formatter.AddFieldBool(L"AlphaBlendFactorSupported", o.AlphaBlendFactorSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS14(const D3D12_FEATURE_DATA_D3D12_OPTIONS14& o) { ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS14"); - ReportFormatter::GetInstance().AddFieldBool(L"AdvancedTextureOpsSupported", o.AdvancedTextureOpsSupported); - ReportFormatter::GetInstance().AddFieldBool(L"WriteableMSAATexturesSupported", o.WriteableMSAATexturesSupported); - ReportFormatter::GetInstance().AddFieldBool(L"IndependentFrontAndBackStencilRefMaskSupported", o.IndependentFrontAndBackStencilRefMaskSupported); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldBool(L"AdvancedTextureOpsSupported", o.AdvancedTextureOpsSupported); + formatter.AddFieldBool(L"WriteableMSAATexturesSupported", o.WriteableMSAATexturesSupported); + formatter.AddFieldBool(L"IndependentFrontAndBackStencilRefMaskSupported", o.IndependentFrontAndBackStencilRefMaskSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS15(const D3D12_FEATURE_DATA_D3D12_OPTIONS15& o) @@ -382,16 +395,17 @@ static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS18(const D3D12_FEATURE_DATA_D3 static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS19(const D3D12_FEATURE_DATA_D3D12_OPTIONS19& o) { ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS19"); - ReportFormatter::GetInstance().AddFieldBool(L"MismatchingOutputDimensionsSupported", o.MismatchingOutputDimensionsSupported); - ReportFormatter::GetInstance().AddFieldUint32(L"SupportedSampleCountsWithNoOutputs", o.SupportedSampleCountsWithNoOutputs); - ReportFormatter::GetInstance().AddFieldBool(L"PointSamplingAddressesNeverRoundUp", o.PointSamplingAddressesNeverRoundUp); - ReportFormatter::GetInstance().AddFieldBool(L"RasterizerDesc2Supported", o.RasterizerDesc2Supported); - ReportFormatter::GetInstance().AddFieldBool(L"NarrowQuadrilateralLinesSupported", o.NarrowQuadrilateralLinesSupported); - ReportFormatter::GetInstance().AddFieldBool(L"AnisoFilterWithPointMipSupported", o.AnisoFilterWithPointMipSupported); - ReportFormatter::GetInstance().AddFieldUint32(L"MaxSamplerDescriptorHeapSize", o.MaxSamplerDescriptorHeapSize); - ReportFormatter::GetInstance().AddFieldUint32(L"MaxSamplerDescriptorHeapSizeWithStaticSamplers", o.MaxSamplerDescriptorHeapSizeWithStaticSamplers); - ReportFormatter::GetInstance().AddFieldUint32(L"MaxViewDescriptorHeapSize", o.MaxViewDescriptorHeapSize); - ReportFormatter::GetInstance().AddFieldBool(L"ComputeOnlyCustomHeapSupported", o.ComputeOnlyCustomHeapSupported); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldBool(L"MismatchingOutputDimensionsSupported", o.MismatchingOutputDimensionsSupported); + formatter.AddFieldUint32(L"SupportedSampleCountsWithNoOutputs", o.SupportedSampleCountsWithNoOutputs); + formatter.AddFieldBool(L"PointSamplingAddressesNeverRoundUp", o.PointSamplingAddressesNeverRoundUp); + formatter.AddFieldBool(L"RasterizerDesc2Supported", o.RasterizerDesc2Supported); + formatter.AddFieldBool(L"NarrowQuadrilateralLinesSupported", o.NarrowQuadrilateralLinesSupported); + formatter.AddFieldBool(L"AnisoFilterWithPointMipSupported", o.AnisoFilterWithPointMipSupported); + formatter.AddFieldUint32(L"MaxSamplerDescriptorHeapSize", o.MaxSamplerDescriptorHeapSize); + formatter.AddFieldUint32(L"MaxSamplerDescriptorHeapSizeWithStaticSamplers", o.MaxSamplerDescriptorHeapSizeWithStaticSamplers); + formatter.AddFieldUint32(L"MaxViewDescriptorHeapSize", o.MaxViewDescriptorHeapSize); + formatter.AddFieldBool(L"ComputeOnlyCustomHeapSupported", o.ComputeOnlyCustomHeapSupported); } static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS20(const D3D12_FEATURE_DATA_D3D12_OPTIONS20& o) @@ -403,11 +417,12 @@ static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS20(const D3D12_FEATURE_DATA_D3 static void Print_D3D12_FEATURE_DATA_D3D12_OPTIONS21(const D3D12_FEATURE_DATA_D3D12_OPTIONS21& o) { - ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS21"); - ReportFormatter::GetInstance().AddFieldEnum(L"WorkGraphsTier", o.WorkGraphsTier, Enum_D3D12_WORK_GRAPHS_TIER); - ReportFormatter::GetInstance().AddFieldEnum(L"ExecuteIndirectTier", o.ExecuteIndirectTier, Enum_D3D12_EXECUTE_INDIRECT_TIER); - ReportFormatter::GetInstance().AddFieldBool(L"SampleCmpGradientAndBiasSupported", o.SampleCmpGradientAndBiasSupported); - ReportFormatter::GetInstance().AddFieldBool(L"ExtendedCommandInfoSupported", o.ExtendedCommandInfoSupported); + ReportScopeObject scope(L"D3D12_FEATURE_DATA_D3D12_OPTIONS21"); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldEnum(L"WorkGraphsTier", o.WorkGraphsTier, Enum_D3D12_WORK_GRAPHS_TIER); + formatter.AddFieldEnum(L"ExecuteIndirectTier", o.ExecuteIndirectTier, Enum_D3D12_EXECUTE_INDIRECT_TIER); + formatter.AddFieldBool(L"SampleCmpGradientAndBiasSupported", o.SampleCmpGradientAndBiasSupported); + formatter.AddFieldBool(L"ExtendedCommandInfoSupported", o.ExtendedCommandInfoSupported); } static void Print_D3D12_FEATURE_DATA_BYTECODE_BYPASS_HASH_SUPPORTED(const D3D12_FEATURE_DATA_BYTECODE_BYPASS_HASH_SUPPORTED& o) @@ -490,28 +505,29 @@ static void PrintVersionData() } ReportScopeObject scope(OutputSpecificString(L"General", L"Header")); + ReportFormatter& formatter = ReportFormatter::GetInstance(); if (IsOutputJson()) { - ReportFormatter::GetInstance().AddFieldString(L"Program", L"D3d12info"); - ReportFormatter::GetInstance().AddFieldString(L"Version", PROGRAM_VERSION); - ReportFormatter::GetInstance().AddFieldString(L"Build Date", MakeBuildDateTime()); - ReportFormatter::GetInstance().AddFieldString(L"Configuration", CONFIG_STR); - ReportFormatter::GetInstance().AddFieldString(L"Configuration bits", CONFIG_BIT_STR); + formatter.AddFieldString(L"Program", L"D3d12info"); + formatter.AddFieldString(L"Version", PROGRAM_VERSION); + formatter.AddFieldString(L"Build Date", MakeBuildDateTime()); + formatter.AddFieldString(L"Configuration", CONFIG_STR); + formatter.AddFieldString(L"Configuration bits", CONFIG_BIT_STR); } - ReportFormatter::GetInstance().AddFieldString(L"Generated on", MakeCurrentDate().c_str()); + formatter.AddFieldString(L"Generated on", MakeCurrentDate().c_str()); #ifdef USE_PREVIEW_AGILITY_SDK if (IsOutputJson()) { - ReportFormatter::GetInstance().AddFieldBool(L"Using preview Agility SDK", true); + formatter.AddFieldBool(L"Using preview Agility SDK", true); } - ReportFormatter::GetInstance().AddFieldUint32(L"D3D12_PREVIEW_SDK_VERSION", uint32_t(D3D12SDKVersion)); + formatter.AddFieldUint32(L"D3D12_PREVIEW_SDK_VERSION", uint32_t(D3D12SDKVersion)); #else if (IsOutputJson()) { - ReportFormatter::GetInstance().AddFieldBool(L"Using preview Agility SDK", false); + formatter.AddFieldBool(L"Using preview Agility SDK", false); } - ReportFormatter::GetInstance().AddFieldUint32(L"D3D12_SDK_VERSION", uint32_t(D3D12SDKVersion)); + formatter.AddFieldUint32(L"D3D12_SDK_VERSION", uint32_t(D3D12SDKVersion)); #endif if(!g_PureD3D12) @@ -553,10 +569,11 @@ static void PrintEnums() static void PrintOsVersionInfo() { ReportScopeObject scope(L"OS Info"); + ReportFormatter& formatter = ReportFormatter::GetInstance(); HMODULE m = GetModuleHandle(L"ntdll.dll"); if(!m) { - ReportFormatter::GetInstance().AddFieldString(L"Windows version", L"Unknown"); + formatter.AddFieldString(L"Windows version", L"Unknown"); return; } @@ -564,7 +581,7 @@ static void PrintOsVersionInfo() RtlGetVersionFunc RtlGetVersion = (RtlGetVersionFunc)GetProcAddress(m, "RtlGetVersion"); if(!RtlGetVersion) { - ReportFormatter::GetInstance().AddFieldString(L"Windows version", L"Unknown"); + formatter.AddFieldString(L"Windows version", L"Unknown"); return; } @@ -572,7 +589,7 @@ static void PrintOsVersionInfo() // Documentation says it always returns success. RtlGetVersion(&osVersionInfo); - ReportFormatter::GetInstance().AddFieldString(L"Windows version", std::format(L"{}.{}.{}", + formatter.AddFieldString(L"Windows version", std::format(L"{}.{}.{}", osVersionInfo.dwMajorVersion, osVersionInfo.dwMinorVersion, osVersionInfo.dwBuildNumber)); } @@ -609,9 +626,10 @@ static void PrintSystemMemoryInfo() if(MEMORYSTATUSEX memStatEx = {sizeof(MEMORYSTATUSEX)}; GlobalMemoryStatusEx(&memStatEx)) { - ReportFormatter::GetInstance().AddFieldSize(L"MEMORYSTATUSEX::ullTotalPhys", memStatEx.ullTotalPhys); - ReportFormatter::GetInstance().AddFieldSize(L"MEMORYSTATUSEX::ullTotalPageFile", memStatEx.ullTotalPageFile); - ReportFormatter::GetInstance().AddFieldSize(L"MEMORYSTATUSEX::ullTotalVirtual", memStatEx.ullTotalVirtual); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldSize(L"MEMORYSTATUSEX::ullTotalPhys", memStatEx.ullTotalPhys); + formatter.AddFieldSize(L"MEMORYSTATUSEX::ullTotalPageFile", memStatEx.ullTotalPageFile); + formatter.AddFieldSize(L"MEMORYSTATUSEX::ullTotalVirtual", memStatEx.ullTotalVirtual); } } @@ -678,15 +696,16 @@ static void EnableExperimentalFeatures() static void PrintAdapterDescMembers(const DXGI_ADAPTER_DESC& desc) { - ReportFormatter::GetInstance().AddFieldString(L"Description", desc.Description); - ReportFormatter::GetInstance().AddFieldVendorId(L"VendorId", desc.VendorId); - ReportFormatter::GetInstance().AddFieldHex32(L"DeviceId", desc.DeviceId); - ReportFormatter::GetInstance().AddFieldSubsystemId(L"SubSysId", desc.SubSysId); - ReportFormatter::GetInstance().AddFieldHex32(L"Revision", desc.Revision); - ReportFormatter::GetInstance().AddFieldSize(L"DedicatedVideoMemory", desc.DedicatedVideoMemory); - ReportFormatter::GetInstance().AddFieldSize(L"DedicatedSystemMemory", desc.DedicatedSystemMemory); - ReportFormatter::GetInstance().AddFieldSize(L"SharedSystemMemory", desc.SharedSystemMemory); - ReportFormatter::GetInstance().AddFieldString(L"AdapterLuid", LuidToStr(desc.AdapterLuid).c_str()); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldString(L"Description", desc.Description); + formatter.AddFieldVendorId(L"VendorId", desc.VendorId); + formatter.AddFieldHex32(L"DeviceId", desc.DeviceId); + formatter.AddFieldSubsystemId(L"SubSysId", desc.SubSysId); + formatter.AddFieldHex32(L"Revision", desc.Revision); + formatter.AddFieldSize(L"DedicatedVideoMemory", desc.DedicatedVideoMemory); + formatter.AddFieldSize(L"DedicatedSystemMemory", desc.DedicatedSystemMemory); + formatter.AddFieldSize(L"SharedSystemMemory", desc.SharedSystemMemory); + formatter.AddFieldString(L"AdapterLuid", LuidToStr(desc.AdapterLuid).c_str()); } static void PrintAdapterDesc1Members(const DXGI_ADAPTER_DESC1& desc1) @@ -818,6 +837,7 @@ static FormatSupportResult CheckFormatSupport(ID3D12Device* device, D3D12_FEATUR static void PrintFormatInformation(ID3D12Device* device) { ReportScopeObject scope(L"Formats"); + ReportFormatter& formatter = ReportFormatter::GetInstance(); D3D12_FEATURE_DATA_FORMAT_SUPPORT formatSupport = {}; D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS msQualityLevels = {}; @@ -841,8 +861,8 @@ static void PrintFormatInformation(ID3D12Device* device) if(formatSupportResult == FormatSupportResult::Ok) { scope2.Enable(); - ReportFormatter::GetInstance().AddFieldFlags(L"Support1", formatSupport.Support1, Enum_D3D12_FORMAT_SUPPORT1); - ReportFormatter::GetInstance().AddFieldFlags(L"Support2", formatSupport.Support2, Enum_D3D12_FORMAT_SUPPORT2); + formatter.AddFieldFlags(L"Support1", formatSupport.Support1, Enum_D3D12_FORMAT_SUPPORT1); + formatter.AddFieldFlags(L"Support2", formatSupport.Support2, Enum_D3D12_FORMAT_SUPPORT2); ReportScopeObjectConditional scope3(IsOutputJson(), L"MultisampleQualityLevels"); msQualityLevels.Format = format; @@ -854,13 +874,13 @@ static void PrintFormatInformation(ID3D12Device* device) if(IsOutputJson()) { ReportScopeObject scope4(std::format(L"{}", msQualityLevels.SampleCount)); - ReportFormatter::GetInstance().AddFieldUint32(L"NumQualityLevels", msQualityLevels.NumQualityLevels); - ReportFormatter::GetInstance().AddFieldUint32(L"Flags", uint32_t(msQualityLevels.Flags)); + formatter.AddFieldUint32(L"NumQualityLevels", msQualityLevels.NumQualityLevels); + formatter.AddFieldUint32(L"Flags", uint32_t(msQualityLevels.Flags)); } else { bool multisampleTiled = (msQualityLevels.Flags & D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_TILED_RESOURCE) != 0; - ReportFormatter::GetInstance().AddFieldString(L"SampleCount", std::format(L"{}: NumQualityLevels = {}{}", msQualityLevels.SampleCount, msQualityLevels.NumQualityLevels, multisampleTiled ? L" D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_TILED_RESOURCE" : L"")); + formatter.AddFieldString(L"SampleCount", std::format(L"{}: NumQualityLevels = {}{}", msQualityLevels.SampleCount, msQualityLevels.NumQualityLevels, multisampleTiled ? L" D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_TILED_RESOURCE" : L"")); } } else @@ -872,7 +892,7 @@ static void PrintFormatInformation(ID3D12Device* device) if(SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &formatInfo, UINT(sizeof formatInfo)))) { scope2.Enable(); - ReportFormatter::GetInstance().AddFieldUint32(L"PlaneCount", formatInfo.PlaneCount); + formatter.AddFieldUint32(L"PlaneCount", formatInfo.PlaneCount); } } } @@ -981,24 +1001,26 @@ static void PrintDeviceOptions(ID3D12Device* device) static void PrintDescriptorSizes(ID3D12Device* device) { ReportScopeObject scope(L"GetDescriptorHandleIncrementSize"); - ReportFormatter::GetInstance().AddFieldUint32(L"D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV", + ReportFormatter& formatter = ReportFormatter::GetInstance(); + formatter.AddFieldUint32(L"D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV", device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)); - ReportFormatter::GetInstance().AddFieldUint32(L"D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER", + formatter.AddFieldUint32(L"D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER", device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER)); - ReportFormatter::GetInstance().AddFieldUint32(L"D3D12_DESCRIPTOR_HEAP_TYPE_RTV", + formatter.AddFieldUint32(L"D3D12_DESCRIPTOR_HEAP_TYPE_RTV", device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV)); - ReportFormatter::GetInstance().AddFieldUint32(L"D3D12_DESCRIPTOR_HEAP_TYPE_DSV", + formatter.AddFieldUint32(L"D3D12_DESCRIPTOR_HEAP_TYPE_DSV", device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV)); } static void PrintMetaCommand(ID3D12Device5* device5, UINT index, const D3D12_META_COMMAND_DESC& desc) { ReportScopeArrayItem scope; + ReportFormatter& formatter = ReportFormatter::GetInstance(); - ReportFormatter::GetInstance().AddFieldString(L"Id", GuidToStr(desc.Id).c_str()); - ReportFormatter::GetInstance().AddFieldString(L"Name", desc.Name); - ReportFormatter::GetInstance().AddFieldFlags(L"InitializationDirtyState", desc.InitializationDirtyState, Enum_D3D12_GRAPHICS_STATES); - ReportFormatter::GetInstance().AddFieldFlags(L"ExecutionDirtyState", desc.ExecutionDirtyState, Enum_D3D12_GRAPHICS_STATES); + formatter.AddFieldString(L"Id", GuidToStr(desc.Id).c_str()); + formatter.AddFieldString(L"Name", desc.Name); + formatter.AddFieldFlags(L"InitializationDirtyState", desc.InitializationDirtyState, Enum_D3D12_GRAPHICS_STATES); + formatter.AddFieldFlags(L"ExecutionDirtyState", desc.ExecutionDirtyState, Enum_D3D12_GRAPHICS_STATES); for(UINT stageIndex = 0; stageIndex < 3; ++stageIndex) { @@ -1012,7 +1034,7 @@ static void PrintMetaCommand(ID3D12Device5* device5, UINT index, const D3D12_MET { ReportScopeObject scope2(Enum_D3D12_META_COMMAND_PARAMETER_STAGE[stageIndex].m_Name); - ReportFormatter::GetInstance().AddFieldUint32(L"TotalStructureSizeInBytes", totalStructureSizeInBytes); + formatter.AddFieldUint32(L"TotalStructureSizeInBytes", totalStructureSizeInBytes); } if(paramCount > 0) @@ -1031,11 +1053,11 @@ static void PrintMetaCommand(ID3D12Device5* device5, UINT index, const D3D12_MET ReportScopeArrayItem scope3; - ReportFormatter::GetInstance().AddFieldString(L"Name", paramDesc.Name); - ReportFormatter::GetInstance().AddFieldEnum(L"Type", paramDesc.Type, Enum_D3D12_META_COMMAND_PARAMETER_TYPE); - ReportFormatter::GetInstance().AddFieldFlags(L"Flags", paramDesc.Flags, Enum_D3D12_META_COMMAND_PARAMETER_FLAGS); - ReportFormatter::GetInstance().AddFieldFlags(L"RequiredResourceState", paramDesc.RequiredResourceState, Enum_D3D12_RESOURCE_STATES); - ReportFormatter::GetInstance().AddFieldUint32(L"StructureOffset", paramDesc.StructureOffset); + formatter.AddFieldString(L"Name", paramDesc.Name); + formatter.AddFieldEnum(L"Type", paramDesc.Type, Enum_D3D12_META_COMMAND_PARAMETER_TYPE); + formatter.AddFieldFlags(L"Flags", paramDesc.Flags, Enum_D3D12_META_COMMAND_PARAMETER_FLAGS); + formatter.AddFieldFlags(L"RequiredResourceState", paramDesc.RequiredResourceState, Enum_D3D12_RESOURCE_STATES); + formatter.AddFieldUint32(L"StructureOffset", paramDesc.StructureOffset); } } } @@ -1119,6 +1141,7 @@ static void PrintDirectSR(ID3D12Device* device) return; ReportScopeArray scope(L"DirectSR"); + ReportFormatter& formatter = ReportFormatter::GetInstance(); for(UINT variantIndex = 0; variantIndex < numVariants; ++variantIndex) { @@ -1127,11 +1150,11 @@ static void PrintDirectSR(ID3D12Device* device) { ReportScopeArrayItem scope2; - ReportFormatter::GetInstance().AddFieldString(L"VariantId", GuidToStr(desc.VariantId).c_str()); - ReportFormatter::GetInstance().AddFieldString(L"VariantName", StrToWstr(desc.VariantName, CP_UTF8).c_str()); - ReportFormatter::GetInstance().AddFieldFlags(L"Flags", desc.Flags, Enum_DSR_SUPERRES_VARIANT_FLAGS); + formatter.AddFieldString(L"VariantId", GuidToStr(desc.VariantId).c_str()); + formatter.AddFieldString(L"VariantName", StrToWstr(desc.VariantName, CP_UTF8).c_str()); + formatter.AddFieldFlags(L"Flags", desc.Flags, Enum_DSR_SUPERRES_VARIANT_FLAGS); PrintDirectSROptimizationRankings(desc.OptimizationRankings); - ReportFormatter::GetInstance().AddFieldEnum(L"OptimalTargetFormat", desc.OptimalTargetFormat, Enum_DXGI_FORMAT); + formatter.AddFieldEnum(L"OptimalTargetFormat", desc.OptimalTargetFormat, Enum_DXGI_FORMAT); } } } diff --git a/Src/NvApiData.cpp b/Src/NvApiData.cpp index 7d9be50..f8ece80 100644 --- a/Src/NvApiData.cpp +++ b/Src/NvApiData.cpp @@ -548,14 +548,15 @@ static bool FindPhysicalGpuAdapterType(NvPhysicalGpuHandle physicalGpuHandle, NV static void PrintCooperativeVectorProperty(size_t index, const NVAPI_COOPERATIVE_VECTOR_PROPERTIES& props) { ReportScopeArrayItem scope; - - ReportFormatter::GetInstance().AddFieldHex32(L"version", props.version); - ReportFormatter::GetInstance().AddFieldEnum(L"inputType", props.inputType, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); - ReportFormatter::GetInstance().AddFieldEnum(L"inputInterpretation", props.inputInterpretation, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); - ReportFormatter::GetInstance().AddFieldEnum(L"matrixInterpretation", props.matrixInterpretation, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); - ReportFormatter::GetInstance().AddFieldEnum(L"biasInterpretation", props.biasInterpretation, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); - ReportFormatter::GetInstance().AddFieldEnum(L"resultType", props.resultType, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); - ReportFormatter::GetInstance().AddFieldBool(L"transpose", props.transpose); + ReportFormatter& formatter = ReportFormatter::GetInstance(); + + formatter.AddFieldHex32(L"version", props.version); + formatter.AddFieldEnum(L"inputType", props.inputType, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); + formatter.AddFieldEnum(L"inputInterpretation", props.inputInterpretation, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); + formatter.AddFieldEnum(L"matrixInterpretation", props.matrixInterpretation, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); + formatter.AddFieldEnum(L"biasInterpretation", props.biasInterpretation, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); + formatter.AddFieldEnum(L"resultType", props.resultType, Enum_NVAPI_COOPERATIVE_VECTOR_COMPONENT_TYPE); + formatter.AddFieldBool(L"transpose", props.transpose); } static void PrintCooperativeVectorProperties(const std::vector& props) @@ -573,12 +574,13 @@ static void PrintCooperativeVectorProperties(const std::vectorm_Value, &supported) == NVAPI_OK) { scope.Enable(); - ReportFormatter::GetInstance().AddFieldBool(ei->m_Name, supported); + formatter.AddFieldBool(ei->m_Name, supported); } } } @@ -657,7 +661,7 @@ void NvAPI_Inititalize_RAII::PrintD3d12DeviceData(ID3D12Device* device) if(NvAPI_D3D12_GetOptimalThreadCountForMesh(device, &threadCount) == NVAPI_OK) { ReportScopeObject scope(L"NvAPI_D3D12_GetOptimalThreadCountForMesh"); - ReportFormatter::GetInstance().AddFieldUint32(L"pThreadCount", (uint32_t)threadCount); + formatter.AddFieldUint32(L"pThreadCount", (uint32_t)threadCount); } } @@ -668,7 +672,7 @@ void NvAPI_Inititalize_RAII::PrintD3d12DeviceData(ID3D12Device* device) &threadReorderingCaps, sizeof threadReorderingCaps) == NVAPI_OK) { scope.Enable(); - ReportFormatter::GetInstance().AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_THREAD_REORDERING", (uint32_t)threadReorderingCaps, + formatter.AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_THREAD_REORDERING", (uint32_t)threadReorderingCaps, Enum_NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAPS); } @@ -677,7 +681,7 @@ void NvAPI_Inititalize_RAII::PrintD3d12DeviceData(ID3D12Device* device) &opacityMicromapCaps, sizeof opacityMicromapCaps) == NVAPI_OK) { scope.Enable(); - ReportFormatter::GetInstance().AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_OPACITY_MICROMAP", (uint32_t)opacityMicromapCaps, + formatter.AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_OPACITY_MICROMAP", (uint32_t)opacityMicromapCaps, Enum_NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS); } @@ -686,7 +690,7 @@ void NvAPI_Inititalize_RAII::PrintD3d12DeviceData(ID3D12Device* device) &displacementMicromapCaps, sizeof displacementMicromapCaps) == NVAPI_OK) { scope.Enable(); - ReportFormatter::GetInstance().AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_DISPLACEMENT_MICROMAP", (uint32_t)displacementMicromapCaps, + formatter.AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_DISPLACEMENT_MICROMAP", (uint32_t)displacementMicromapCaps, Enum_NVAPI_D3D12_RAYTRACING_DISPLACEMENT_MICROMAP_CAPS); } @@ -695,7 +699,7 @@ void NvAPI_Inititalize_RAII::PrintD3d12DeviceData(ID3D12Device* device) &caps, sizeof caps) == NVAPI_OK) { scope.Enable(); - ReportFormatter::GetInstance().AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_CLUSTER_OPERATIONS", (uint32_t)caps, + formatter.AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_CLUSTER_OPERATIONS", (uint32_t)caps, Enum_NVAPI_D3D12_RAYTRACING_CLUSTER_OPERATIONS_CAPS); } @@ -704,7 +708,7 @@ void NvAPI_Inititalize_RAII::PrintD3d12DeviceData(ID3D12Device* device) &caps, sizeof caps) == NVAPI_OK) { scope.Enable(); - ReportFormatter::GetInstance().AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_PARTITIONED_TLAS", (uint32_t)caps, + formatter.AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_PARTITIONED_TLAS", (uint32_t)caps, Enum_NVAPI_D3D12_RAYTRACING_PARTITIONED_TLAS_CAPS); } @@ -713,7 +717,7 @@ void NvAPI_Inititalize_RAII::PrintD3d12DeviceData(ID3D12Device* device) &caps, sizeof caps) == NVAPI_OK) { scope.Enable(); - ReportFormatter::GetInstance().AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_SPHERES", (uint32_t)caps, + formatter.AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_SPHERES", (uint32_t)caps, Enum_NVAPI_D3D12_RAYTRACING_SPHERES_CAPS); } @@ -722,7 +726,7 @@ void NvAPI_Inititalize_RAII::PrintD3d12DeviceData(ID3D12Device* device) &caps, sizeof caps) == NVAPI_OK) { scope.Enable(); - ReportFormatter::GetInstance().AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_LINEAR_SWEPT_SPHERES", (uint32_t)caps, + formatter.AddFieldEnum(L"NVAPI_D3D12_RAYTRACING_CAPS_TYPE_LINEAR_SWEPT_SPHERES", (uint32_t)caps, Enum_NVAPI_D3D12_RAYTRACING_LINEAR_SWEPT_SPHERES_CAPS); } } @@ -736,17 +740,17 @@ void NvAPI_Inititalize_RAII::PrintD3d12DeviceData(ID3D12Device* device) if(NvAPI_D3D12_QueryWorkstationFeatureProperties(device, ¶ms) == NVAPI_OK) { scope.Enable(); - ReportFormatter::GetInstance().AddFieldBool(L"NV_D3D12_WORKSTATION_FEATURE_TYPE_PRESENT_BARRIER - supported", params.supported); + formatter.AddFieldBool(L"NV_D3D12_WORKSTATION_FEATURE_TYPE_PRESENT_BARRIER - supported", params.supported); } params.workstationFeatureType = NV_D3D12_WORKSTATION_FEATURE_TYPE_RDMA_BAR1_SUPPORT; if(NvAPI_D3D12_QueryWorkstationFeatureProperties(device, ¶ms) == NVAPI_OK) { scope.Enable(); - ReportFormatter::GetInstance().AddFieldBool(L"NV_D3D12_WORKSTATION_FEATURE_TYPE_RDMA_BAR1_SUPPORT - supported", params.supported); + formatter.AddFieldBool(L"NV_D3D12_WORKSTATION_FEATURE_TYPE_RDMA_BAR1_SUPPORT - supported", params.supported); if (params.supported) { - ReportFormatter::GetInstance().AddFieldUint64(L"NV_D3D12_WORKSTATION_FEATURE_TYPE_RDMA_BAR1_SUPPORT - rdmaHeapSize", params.rdmaInfo.rdmaHeapSize); + formatter.AddFieldUint64(L"NV_D3D12_WORKSTATION_FEATURE_TYPE_RDMA_BAR1_SUPPORT - rdmaHeapSize", params.rdmaInfo.rdmaHeapSize); } } } @@ -756,7 +760,7 @@ void NvAPI_Inititalize_RAII::PrintD3d12DeviceData(ID3D12Device* device) if(NvAPI_D3D12_GetNeedsAppFPBlendClamping(device, &appClampNeeded) == NVAPI_OK) { ReportScopeObject scope(L"NvAPI_D3D12_GetNeedsAppFPBlendClamping"); - ReportFormatter::GetInstance().AddFieldBool(L"pAppClampNeeded", appClampNeeded); + formatter.AddFieldBool(L"pAppClampNeeded", appClampNeeded); } } @@ -783,68 +787,69 @@ void NvAPI_Inititalize_RAII::PrintPhysicalGpuData(const LUID& adapterLuid) return; ReportScopeObject scope(L"NvPhysicalGpuHandle"); + ReportFormatter& formatter = ReportFormatter::GetInstance(); if(NV_ADAPTER_TYPE adapterType; FindPhysicalGpuAdapterType(gpu, adapterType)) { - ReportFormatter::GetInstance().AddFieldFlags(L"adapterType", (uint32_t)adapterType, Enum_NV_ADAPTER_TYPE); + formatter.AddFieldFlags(L"adapterType", (uint32_t)adapterType, Enum_NV_ADAPTER_TYPE); } NV_SYSTEM_TYPE systemType = {}; if(NvAPI_GPU_GetSystemType(gpu, &systemType) == NVAPI_OK) - ReportFormatter::GetInstance().AddFieldEnum(L"NvAPI_GPU_GetSystemType", systemType, Enum_NV_SYSTEM_TYPE); + formatter.AddFieldEnum(L"NvAPI_GPU_GetSystemType", systemType, Enum_NV_SYSTEM_TYPE); NvAPI_ShortString name = {}; if(NvAPI_GPU_GetFullName(gpu, name) == NVAPI_OK) - ReportFormatter::GetInstance().AddFieldString(L"NvAPI_GPU_GetFullName", StrToWstr(name, CP_ACP).c_str()); + formatter.AddFieldString(L"NvAPI_GPU_GetFullName", StrToWstr(name, CP_ACP).c_str()); NvU32 DeviceId = 0, SubSystemId = 0, RevisionId = 0, ExtDeviceId = 0; if(NvAPI_GPU_GetPCIIdentifiers(gpu, &DeviceId, &SubSystemId, &RevisionId, &ExtDeviceId) == NVAPI_OK) { - ReportFormatter::GetInstance().AddFieldHex32(L"NvAPI_GPU_GetPCIIdentifiers - pDeviceID", DeviceId); - ReportFormatter::GetInstance().AddFieldSubsystemId(L"NvAPI_GPU_GetPCIIdentifiers - pSubSystemId", SubSystemId); - ReportFormatter::GetInstance().AddFieldHex32(L"NvAPI_GPU_GetPCIIdentifiers - pRevisionId", RevisionId); - ReportFormatter::GetInstance().AddFieldHex32(L"NvAPI_GPU_GetPCIIdentifiers - pExtDeviceId", ExtDeviceId); + formatter.AddFieldHex32(L"NvAPI_GPU_GetPCIIdentifiers - pDeviceID", DeviceId); + formatter.AddFieldSubsystemId(L"NvAPI_GPU_GetPCIIdentifiers - pSubSystemId", SubSystemId); + formatter.AddFieldHex32(L"NvAPI_GPU_GetPCIIdentifiers - pRevisionId", RevisionId); + formatter.AddFieldHex32(L"NvAPI_GPU_GetPCIIdentifiers - pExtDeviceId", ExtDeviceId); } NV_GPU_TYPE gpuType = {}; if(NvAPI_GPU_GetGPUType(gpu, &gpuType) == NVAPI_OK) - ReportFormatter::GetInstance().AddFieldEnum(L"NvAPI_GPU_GetGPUType", gpuType, Enum_NV_GPU_TYPE); + formatter.AddFieldEnum(L"NvAPI_GPU_GetGPUType", gpuType, Enum_NV_GPU_TYPE); NV_GPU_BUS_TYPE busType = {}; if(NvAPI_GPU_GetBusType(gpu, &busType) == NVAPI_OK) - ReportFormatter::GetInstance().AddFieldEnum(L"NvAPI_GPU_GetBusType", busType, Enum_NV_GPU_BUS_TYPE); + formatter.AddFieldEnum(L"NvAPI_GPU_GetBusType", busType, Enum_NV_GPU_BUS_TYPE); NvU32 biosRevision = 0; if(NvAPI_GPU_GetVbiosRevision(gpu, &biosRevision) == NVAPI_OK) - ReportFormatter::GetInstance().AddFieldUint32(L"NvAPI_GPU_GetVbiosRevision", biosRevision); + formatter.AddFieldUint32(L"NvAPI_GPU_GetVbiosRevision", biosRevision); NvU32 biosOemRevision = 0; if(NvAPI_GPU_GetVbiosOEMRevision(gpu, &biosOemRevision) == NVAPI_OK) - ReportFormatter::GetInstance().AddFieldUint32(L"NvAPI_GPU_GetVbiosOEMRevision", biosOemRevision); + formatter.AddFieldUint32(L"NvAPI_GPU_GetVbiosOEMRevision", biosOemRevision); NvAPI_ShortString biosVersionString = {}; if(NvAPI_GPU_GetVbiosVersionString(gpu, biosVersionString) == NVAPI_OK) - ReportFormatter::GetInstance().AddFieldString(L"NvAPI_GPU_GetVbiosVersionString", StrToWstr(biosVersionString, CP_ACP).c_str()); + formatter.AddFieldString(L"NvAPI_GPU_GetVbiosVersionString", StrToWstr(biosVersionString, CP_ACP).c_str()); NvU32 physicalFrameBufferSize = 0; if(NvAPI_GPU_GetPhysicalFrameBufferSize(gpu, &physicalFrameBufferSize) == NVAPI_OK) - ReportFormatter::GetInstance().AddFieldSizeKilobytes(L"NvAPI_GPU_GetPhysicalFrameBufferSize", physicalFrameBufferSize); + formatter.AddFieldSizeKilobytes(L"NvAPI_GPU_GetPhysicalFrameBufferSize", physicalFrameBufferSize); NvU32 virtualFrameBufferSize = 0; if(NvAPI_GPU_GetVirtualFrameBufferSize(gpu, &virtualFrameBufferSize) == NVAPI_OK) - ReportFormatter::GetInstance().AddFieldSizeKilobytes(L"NvAPI_GPU_GetVirtualFrameBufferSize", virtualFrameBufferSize); + formatter.AddFieldSizeKilobytes(L"NvAPI_GPU_GetVirtualFrameBufferSize", virtualFrameBufferSize); NV_GPU_ARCH_INFO archInfo = {NV_GPU_ARCH_INFO_VER}; if(NvAPI_GPU_GetArchInfo(gpu, &archInfo) == NVAPI_OK) { - ReportFormatter::GetInstance().AddFieldEnum(L"NvAPI_GPU_GetArchInfo - NV_GPU_ARCH_INFO::architecture_id", archInfo.architecture_id, Enum_NV_GPU_ARCHITECTURE_ID); - ReportFormatter::GetInstance().AddFieldNvidiaImplementationID(L"NvAPI_GPU_GetArchInfo - NV_GPU_ARCH_INFO::implementation_id", (uint32_t)archInfo.architecture_id, (uint32_t)archInfo.implementation_id, Enum_NV_ARCH_plus_IMPLEMENTATION_ID); - ReportFormatter::GetInstance().AddFieldEnum(L"NvAPI_GPU_GetArchInfo - NV_GPU_ARCH_INFO::revision_id", archInfo.revision_id, Enum_NV_GPU_CHIP_REVISION); + formatter.AddFieldEnum(L"NvAPI_GPU_GetArchInfo - NV_GPU_ARCH_INFO::architecture_id", archInfo.architecture_id, Enum_NV_GPU_ARCHITECTURE_ID); + formatter.AddFieldNvidiaImplementationID(L"NvAPI_GPU_GetArchInfo - NV_GPU_ARCH_INFO::implementation_id", (uint32_t)archInfo.architecture_id, (uint32_t)archInfo.implementation_id, Enum_NV_ARCH_plus_IMPLEMENTATION_ID); + formatter.AddFieldEnum(L"NvAPI_GPU_GetArchInfo - NV_GPU_ARCH_INFO::revision_id", archInfo.revision_id, Enum_NV_GPU_CHIP_REVISION); } NV_GPU_VR_READY vrReady = {NV_GPU_VR_READY_VER}; if(NvAPI_GPU_GetVRReadyData(gpu, &vrReady) == NVAPI_OK) - ReportFormatter::GetInstance().AddFieldBool(L"NvAPI_GPU_GetVRReadyData - NV_GPU_VR_READY::isVRReady", vrReady.isVRReady != 0); + formatter.AddFieldBool(L"NvAPI_GPU_GetVRReadyData - NV_GPU_VR_READY::isVRReady", vrReady.isVRReady != 0); NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM queryIlluminationSupportParm = { .version = NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM_VER, @@ -854,7 +859,7 @@ void NvAPI_Inititalize_RAII::PrintPhysicalGpuData(const LUID& adapterLuid) queryIlluminationSupportParm.Attribute = (NV_GPU_ILLUMINATION_ATTRIB)ei->m_Value; if(NvAPI_GPU_QueryIlluminationSupport(&queryIlluminationSupportParm) == NVAPI_OK) { - ReportFormatter::GetInstance().AddFieldBool(std::format(L"NvAPI_GPU_QueryIlluminationSupport({})", ei->m_Name).c_str(), + formatter.AddFieldBool(std::format(L"NvAPI_GPU_QueryIlluminationSupport({})", ei->m_Name).c_str(), queryIlluminationSupportParm.bSupported != 0); } } @@ -862,7 +867,7 @@ void NvAPI_Inititalize_RAII::PrintPhysicalGpuData(const LUID& adapterLuid) for(const EnumItem* ei = Enum_NV_GPU_WORKSTATION_FEATURE_TYPE; ei->m_Name != nullptr; ++ei) { NvAPI_Status status = NvAPI_GPU_QueryWorkstationFeatureSupport(gpu, (NV_GPU_WORKSTATION_FEATURE_TYPE)ei->m_Value); - ReportFormatter::GetInstance().AddFieldEnumSigned(std::format(L"NvAPI_GPU_QueryWorkstationFeatureSupport({})", ei->m_Name).c_str(), + formatter.AddFieldEnumSigned(std::format(L"NvAPI_GPU_QueryWorkstationFeatureSupport({})", ei->m_Name).c_str(), status, Enum_NvAPI_Status); } @@ -870,48 +875,48 @@ void NvAPI_Inititalize_RAII::PrintPhysicalGpuData(const LUID& adapterLuid) NV_GPU_MEMORY_INFO_EX memInfo = {NV_GPU_MEMORY_INFO_EX_VER}; if(NvAPI_GPU_GetMemoryInfoEx(gpu, &memInfo) == NVAPI_OK) { - ReportFormatter::GetInstance().AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemory", memInfo.dedicatedVideoMemory); - ReportFormatter::GetInstance().AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::availableDedicatedVideoMemory", memInfo.availableDedicatedVideoMemory); - ReportFormatter::GetInstance().AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::systemVideoMemory", memInfo.systemVideoMemory); - ReportFormatter::GetInstance().AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::sharedSystemMemory", memInfo.sharedSystemMemory); - ReportFormatter::GetInstance().AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::curAvailableDedicatedVideoMemory", memInfo.curAvailableDedicatedVideoMemory); - ReportFormatter::GetInstance().AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemoryEvictionsSize", memInfo.dedicatedVideoMemoryEvictionsSize); - ReportFormatter::GetInstance().AddFieldUint64(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemoryEvictionCount", memInfo.dedicatedVideoMemoryEvictionCount); - ReportFormatter::GetInstance().AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemoryPromotionsSize", memInfo.dedicatedVideoMemoryPromotionsSize); - ReportFormatter::GetInstance().AddFieldUint64(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemoryPromotionCount", memInfo.dedicatedVideoMemoryPromotionCount); + formatter.AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemory", memInfo.dedicatedVideoMemory); + formatter.AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::availableDedicatedVideoMemory", memInfo.availableDedicatedVideoMemory); + formatter.AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::systemVideoMemory", memInfo.systemVideoMemory); + formatter.AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::sharedSystemMemory", memInfo.sharedSystemMemory); + formatter.AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::curAvailableDedicatedVideoMemory", memInfo.curAvailableDedicatedVideoMemory); + formatter.AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemoryEvictionsSize", memInfo.dedicatedVideoMemoryEvictionsSize); + formatter.AddFieldUint64(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemoryEvictionCount", memInfo.dedicatedVideoMemoryEvictionCount); + formatter.AddFieldSize(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemoryPromotionsSize", memInfo.dedicatedVideoMemoryPromotionsSize); + formatter.AddFieldUint64(L"NvAPI_GPU_GetMemoryInfoEx - NV_GPU_MEMORY_INFO_EX::dedicatedVideoMemoryPromotionCount", memInfo.dedicatedVideoMemoryPromotionCount); } } NvU32 shaderSubPipeCount = 0; if(NvAPI_GPU_GetShaderSubPipeCount(gpu, &shaderSubPipeCount) == NVAPI_OK) - ReportFormatter::GetInstance().AddFieldUint32(L"NvAPI_GPU_GetShaderSubPipeCount", shaderSubPipeCount); + formatter.AddFieldUint32(L"NvAPI_GPU_GetShaderSubPipeCount", shaderSubPipeCount); NvU32 gpuCoreCount = 0; if(NvAPI_GPU_GetGpuCoreCount(gpu, &gpuCoreCount) == NVAPI_OK) - ReportFormatter::GetInstance().AddFieldUint32(L"NvAPI_GPU_GetGpuCoreCount", gpuCoreCount); + formatter.AddFieldUint32(L"NvAPI_GPU_GetGpuCoreCount", gpuCoreCount); NV_GPU_ECC_STATUS_INFO GPUECCStatusInfo = {NV_GPU_ECC_STATUS_INFO_VER}; if(NvAPI_GPU_GetECCStatusInfo(gpu, &GPUECCStatusInfo) == NVAPI_OK) { - ReportFormatter::GetInstance().AddFieldBool(L"NvAPI_GPU_GetECCStatusInfo - NV_GPU_ECC_STATUS_INFO::isSupported", GPUECCStatusInfo.isSupported != 0); - ReportFormatter::GetInstance().AddFieldEnum(L"NvAPI_GPU_GetECCStatusInfo - NV_GPU_ECC_STATUS_INFO::configurationOptions", GPUECCStatusInfo.configurationOptions, + formatter.AddFieldBool(L"NvAPI_GPU_GetECCStatusInfo - NV_GPU_ECC_STATUS_INFO::isSupported", GPUECCStatusInfo.isSupported != 0); + formatter.AddFieldEnum(L"NvAPI_GPU_GetECCStatusInfo - NV_GPU_ECC_STATUS_INFO::configurationOptions", GPUECCStatusInfo.configurationOptions, Enum_NV_ECC_CONFIGURATION); - ReportFormatter::GetInstance().AddFieldBool(L"NvAPI_GPU_GetECCStatusInfo - NV_GPU_ECC_STATUS_INFO::isEnabled", GPUECCStatusInfo.isEnabled != 0); + formatter.AddFieldBool(L"NvAPI_GPU_GetECCStatusInfo - NV_GPU_ECC_STATUS_INFO::isEnabled", GPUECCStatusInfo.isEnabled != 0); } { NvU32 busWidth = 0; if(NvAPI_GPU_GetRamBusWidth(gpu, &busWidth) == NVAPI_OK) - ReportFormatter::GetInstance().AddFieldUint32(L"NvAPI_GPU_GetRamBusWidth", busWidth); + formatter.AddFieldUint32(L"NvAPI_GPU_GetRamBusWidth", busWidth); } { NV_GPU_INFO gpuInfo = {NV_GPU_INFO_VER}; if(NvAPI_GPU_GetGPUInfo(gpu, &gpuInfo) == NVAPI_OK) { - ReportFormatter::GetInstance().AddFieldBool(L"NvAPI_GPU_GetGPUInfo - NV_GPU_INFO::bIsExternalGpu", gpuInfo.bIsExternalGpu); - ReportFormatter::GetInstance().AddFieldUint32(L"NvAPI_GPU_GetGPUInfo - NV_GPU_INFO::rayTracingCores", gpuInfo.rayTracingCores); - ReportFormatter::GetInstance().AddFieldUint32(L"NvAPI_GPU_GetGPUInfo - NV_GPU_INFO::tensorCores", gpuInfo.tensorCores); + formatter.AddFieldBool(L"NvAPI_GPU_GetGPUInfo - NV_GPU_INFO::bIsExternalGpu", gpuInfo.bIsExternalGpu); + formatter.AddFieldUint32(L"NvAPI_GPU_GetGPUInfo - NV_GPU_INFO::rayTracingCores", gpuInfo.rayTracingCores); + formatter.AddFieldUint32(L"NvAPI_GPU_GetGPUInfo - NV_GPU_INFO::tensorCores", gpuInfo.tensorCores); } } @@ -919,7 +924,7 @@ void NvAPI_Inititalize_RAII::PrintPhysicalGpuData(const LUID& adapterLuid) NV_GPU_GSP_INFO gspInfo = {NV_GPU_GSP_INFO_VER}; if(NvAPI_GPU_GetGspFeatures(gpu, &gspInfo) == NVAPI_OK) { - ReportFormatter::GetInstance().AddFieldHexBytes(L"NvAPI_GPU_GetGspFeatures - NV_GPU_GSP_INFO::firmwareVersion", + formatter.AddFieldHexBytes(L"NvAPI_GPU_GetGspFeatures - NV_GPU_GSP_INFO::firmwareVersion", gspInfo.firmwareVersion, NVAPI_GPU_MAX_BUILD_VERSION_LENGTH); } } diff --git a/Src/VulkanData.cpp b/Src/VulkanData.cpp index 3631a09..5ff53ed 100644 --- a/Src/VulkanData.cpp +++ b/Src/VulkanData.cpp @@ -187,6 +187,7 @@ Vulkan_Initialize_RAII::~Vulkan_Initialize_RAII() void Vulkan_Initialize_RAII::PrintData(const DXGI_ADAPTER_DESC& adapterDesc) { assert(IsInitialized()); + ReportFormatter& formatter = ReportFormatter::GetInstance(); size_t physDevIndex = SIZE_MAX; if(!FindPhysicalDevice(adapterDesc, physDevIndex)) @@ -196,31 +197,31 @@ void Vulkan_Initialize_RAII::PrintData(const DXGI_ADAPTER_DESC& adapterDesc) { const VkPhysicalDeviceProperties& props = propSet.properties2.properties; ReportScopeObject region(L"VkPhysicalDeviceProperties"); - ReportFormatter::GetInstance().AddFieldString(L"apiVersion", std::format(L"{}.{}.{}", + formatter.AddFieldString(L"apiVersion", std::format(L"{}.{}.{}", VK_API_VERSION_MAJOR(props.apiVersion), VK_API_VERSION_MINOR(props.apiVersion), VK_API_VERSION_PATCH(props.apiVersion)).c_str()); - ReportFormatter::GetInstance().AddFieldUint32(L"driverVersion", props.driverVersion); - ReportFormatter::GetInstance().AddFieldVendorId(L"vendorID", props.vendorID); - ReportFormatter::GetInstance().AddFieldHex32(L"deviceID", props.deviceID); - ReportFormatter::GetInstance().AddFieldEnum(L"deviceType", props.deviceType, Enum_VkPhysicalDeviceType); - ReportFormatter::GetInstance().AddFieldString(L"deviceName", StrToWstr(props.deviceName, CP_UTF8).c_str()); + formatter.AddFieldUint32(L"driverVersion", props.driverVersion); + formatter.AddFieldVendorId(L"vendorID", props.vendorID); + formatter.AddFieldHex32(L"deviceID", props.deviceID); + formatter.AddFieldEnum(L"deviceType", props.deviceType, Enum_VkPhysicalDeviceType); + formatter.AddFieldString(L"deviceName", StrToWstr(props.deviceName, CP_UTF8).c_str()); } { const VkPhysicalDeviceIDProperties& IDProps = propSet.IDProperties; ReportScopeObject region(L"VkPhysicalDeviceIDProperties"); - ReportFormatter::GetInstance().AddFieldHexBytes(L"deviceUUID", IDProps.deviceUUID, VK_UUID_SIZE); - ReportFormatter::GetInstance().AddFieldHexBytes(L"driverUUID", IDProps.driverUUID, VK_UUID_SIZE); + formatter.AddFieldHexBytes(L"deviceUUID", IDProps.deviceUUID, VK_UUID_SIZE); + formatter.AddFieldHexBytes(L"driverUUID", IDProps.driverUUID, VK_UUID_SIZE); if(IDProps.deviceLUIDValid) - ReportFormatter::GetInstance().AddFieldHexBytes(L"deviceLUID", IDProps.deviceLUID, VK_LUID_SIZE); + formatter.AddFieldHexBytes(L"deviceLUID", IDProps.deviceLUID, VK_LUID_SIZE); } if(g_ApiVersion >= VK_API_VERSION_1_2) { const VkPhysicalDeviceVulkan12Properties& vulkan12Props = propSet.vulkan12Properties; ReportScopeObject region(L"VkPhysicalDeviceVulkan12Properties"); - ReportFormatter::GetInstance().AddFieldEnum(L"driverID", vulkan12Props.driverID, Enum_VkDriverId); - ReportFormatter::GetInstance().AddFieldString(L"driverName", StrToWstr(vulkan12Props.driverName, CP_UTF8).c_str()); - ReportFormatter::GetInstance().AddFieldString(L"driverInfo", StrToWstr(vulkan12Props.driverInfo, CP_UTF8).c_str()); + formatter.AddFieldEnum(L"driverID", vulkan12Props.driverID, Enum_VkDriverId); + formatter.AddFieldString(L"driverName", StrToWstr(vulkan12Props.driverName, CP_UTF8).c_str()); + formatter.AddFieldString(L"driverInfo", StrToWstr(vulkan12Props.driverInfo, CP_UTF8).c_str()); } } From d22ebfdaeddc327e4e7900eb64e48e8500b4ac1f Mon Sep 17 00:00:00 2001 From: Dmytro Bulatov Date: Thu, 27 Feb 2025 05:10:00 +0900 Subject: [PATCH 3/6] Fixed build on latest VS --- Src/Main.cpp | 25 ++++++++++--------- .../ConsoleReportFormatter.cpp | 17 ++++++++++--- Src/ReportFormatter/JSONReportFormatter.cpp | 3 ++- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/Src/Main.cpp b/Src/Main.cpp index 16fd632..9caf484 100644 --- a/Src/Main.cpp +++ b/Src/Main.cpp @@ -17,6 +17,12 @@ For more information, see files README.md, LICENSE.txt. #include "Printer.hpp" #include "ReportFormatter/ReportFormatter.hpp" +#define WIDE_CHAR_STRING_HELPER(x) L ## x +#define WIDE_CHAR_STRING(x) WIDE_CHAR_STRING_HELPER(x) +constexpr const wchar_t* BUILD_TIME = WIDE_CHAR_STRING(__DATE__) L" " WIDE_CHAR_STRING(__TIME__); +#undef WIDE_CHAR_STRING +#undef WIDE_CHAR_STRING_HELPER + // For Direct3D 12 Agility SDK extern "C" { @@ -452,13 +458,6 @@ static void Print_DXGI_QUERY_VIDEO_MEMORY_INFO(const DXGI_QUERY_VIDEO_MEMORY_INF ReportFormatter::GetInstance().AddFieldSize(L"AvailableForReservation", videoMemoryInfo.AvailableForReservation); } -static wstring MakeBuildDateTime() -{ - wchar_t s[128]; - swprintf_s(s, L"%hs, %hs", __DATE__, __TIME__); - return wstring{s}; -} - #ifdef _DEBUG static const wchar_t* const CONFIG_STR = L"Debug"; #else @@ -490,7 +489,7 @@ static void PrintVersionHeader() #endif Printer::PrintString(L"============================\n"); Printer::PrintFormat(L"D3D12INFO {}{}\n", std::make_wformat_args(PROGRAM_VERSION, AGILITY_SDK_NOTE)); - Printer::PrintFormat(L"BuildDate: {}\n", std::make_wformat_args(MakeBuildDateTime())); + Printer::PrintFormat(L"BuildDate: {}\n", std::make_wformat_args(BUILD_TIME)); Printer::PrintFormat(L"Configuration: {}, {}\n", std::make_wformat_args(CONFIG_STR, CONFIG_BIT_STR)); Printer::PrintString(L"============================"); } @@ -511,7 +510,7 @@ static void PrintVersionData() { formatter.AddFieldString(L"Program", L"D3d12info"); formatter.AddFieldString(L"Version", PROGRAM_VERSION); - formatter.AddFieldString(L"Build Date", MakeBuildDateTime()); + formatter.AddFieldString(L"Build Date", BUILD_TIME); formatter.AddFieldString(L"Configuration", CONFIG_STR); formatter.AddFieldString(L"Configuration bits", CONFIG_BIT_STR); } @@ -1816,7 +1815,7 @@ int wmain3(int argc, wchar_t** argv) { if (!Printer::Initialize(true, g_OutputFilePath)) { - ErrorPrinter::PrintFormat(L"Could not open file for writing: {}\n", std::make_wformat_args(g_OutputFilePath.c_str())); + ErrorPrinter::PrintFormat(L"Could not open file for writing: {}\n", std::make_wformat_args(g_OutputFilePath)); return PROGRAM_EXIT_ERROR_INIT; } } @@ -1968,7 +1967,8 @@ int wmain2(int argc, wchar_t** argv) } catch(const std::exception& ex) { - ErrorPrinter::PrintFormat("ERROR: {}\n", std::make_format_args(ex.what())); + const char* errorMessage = ex.what(); + ErrorPrinter::PrintFormat("ERROR: {}\n", std::make_format_args(errorMessage)); return PROGRAM_EXIT_ERROR_EXCEPTION; } catch(...) @@ -1986,7 +1986,8 @@ int wmain(int argc, wchar_t** argv) } __except(EXCEPTION_EXECUTE_HANDLER) { - ErrorPrinter::PrintFormat("STRUCTURED EXCEPTION: 0x{:08X}\n", std::make_format_args(GetExceptionCode())); + unsigned long exceptionCode = GetExceptionCode(); + ErrorPrinter::PrintFormat("STRUCTURED EXCEPTION: 0x{:08X}\n", std::make_format_args(exceptionCode)); return PROGRAM_EXIT_ERROR_SEH_EXCEPTION; } } diff --git a/Src/ReportFormatter/ConsoleReportFormatter.cpp b/Src/ReportFormatter/ConsoleReportFormatter.cpp index 56f6d5c..6defdc9 100644 --- a/Src/ReportFormatter/ConsoleReportFormatter.cpp +++ b/Src/ReportFormatter/ConsoleReportFormatter.cpp @@ -111,7 +111,8 @@ void ConsoleReportFormatter::AddFieldBool(std::wstring_view name, bool value) { assert(!name.empty()); PushElement(); - Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, (value ? L"TRUE" : L"FALSE"))); + const wchar_t* boolStr = value ? L"TRUE" : L"FALSE"; + Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, boolStr)); } void ConsoleReportFormatter::AddFieldUint32(std::wstring_view name, uint32_t value, std::wstring_view unit /*= {}*/) @@ -160,7 +161,8 @@ void ConsoleReportFormatter::AddFieldSize(std::wstring_view name, uint64_t value } else { - Printer::PrintFormat(L"{} = {:.2f} {} ({} B)", std::make_wformat_args(name, double(value) / scale, units[selectedUnit], value)); + double valueScaled = double(value) / scale; + Printer::PrintFormat(L"{} = {:.2f} {} ({} B)", std::make_wformat_args(name, valueScaled, units[selectedUnit], value)); } } @@ -336,14 +338,21 @@ void ConsoleReportFormatter::AddFieldMicrosoftVersion(std::wstring_view name, ui { assert(!name.empty()); PushElement(); - Printer::PrintFormat(L"{} = {}.{}.{}.{}", std::make_wformat_args(name, value >> 48, (value >> 32) & 0xFFFF, (value >> 16) & 0xFFFF, value & 0xFFFF)); + uint64_t major = value >> 48; + uint64_t minor = (value >> 32) & 0xFFFF; + uint64_t build = (value >> 16) & 0xFFFF; + uint64_t revision = value & 0xFFFF; + Printer::PrintFormat(L"{} = {}.{}.{}.{}", std::make_wformat_args(name, major, minor, build, revision)); } void ConsoleReportFormatter::AddFieldAMDVersion(std::wstring_view name, uint64_t value) { assert(!name.empty()); PushElement(); - Printer::PrintFormat(L"{} = {}.{}.{}", std::make_wformat_args(name, value >> 22, (value >> 12) & 0b11'1111'1111, value & 0b1111'1111'1111)); + uint64_t major = value >> 22; + uint64_t minor = (value >> 12) & 0b11'1111'1111; + uint64_t patch = value & 0b1111'1111'1111; + Printer::PrintFormat(L"{} = {}.{}.{}", std::make_wformat_args(name, major, minor, patch)); } void ConsoleReportFormatter::AddFieldNvidiaImplementationID(std::wstring_view name, uint32_t architectureId, uint32_t implementationId, const EnumItem* architecturePlusImplementationIDEnum) diff --git a/Src/ReportFormatter/JSONReportFormatter.cpp b/Src/ReportFormatter/JSONReportFormatter.cpp index 870e6ba..39e90f9 100644 --- a/Src/ReportFormatter/JSONReportFormatter.cpp +++ b/Src/ReportFormatter/JSONReportFormatter.cpp @@ -87,7 +87,8 @@ void JSONReportFormatter::AddFieldBool(std::wstring_view name, bool value) { assert(!name.empty()); PushNewElement(); - Printer::PrintFormat(m_PrettyPrint ? L"\"{}\": {}" : L"\"{}\":{}", std::make_wformat_args(name, value ? L"true" : L"false")); + const wchar_t* boolStr = value ? L"true" : L"false"; + Printer::PrintFormat(m_PrettyPrint ? L"\"{}\": {}" : L"\"{}\":{}", std::make_wformat_args(name, boolStr)); } void JSONReportFormatter::AddFieldUint32(std::wstring_view name, uint32_t value, std::wstring_view unit /* = {}*/) From 0d124e83e4f333ce1efd4b9429366f0ac0c04cc2 Mon Sep 17 00:00:00 2001 From: Dmytro Bulatov Date: Fri, 28 Feb 2025 05:47:40 +0900 Subject: [PATCH 4/6] Fixed review comments --- CMakeLists.txt | 4 +- README.md | 4 +- Src/Enums.hpp | 2 - Src/Main.cpp | 95 +- Src/Printer.cpp | 32 +- Src/Printer.hpp | 11 +- Src/ReportFormatter/JSONReportFormatter.cpp | 26 +- Src/ReportFormatter/JSONReportFormatter.hpp | 5 +- Src/ReportFormatter/ReportFormatter.cpp | 91 +- Src/ReportFormatter/ReportFormatter.hpp | 93 +- ...tFormatter.cpp => TextReportFormatter.cpp} | 888 +++++++++--------- ...tFormatter.hpp => TextReportFormatter.hpp} | 145 ++- Src/pch.hpp | 22 +- 13 files changed, 717 insertions(+), 701 deletions(-) rename Src/ReportFormatter/{ConsoleReportFormatter.cpp => TextReportFormatter.cpp} (62%) rename Src/ReportFormatter/{ConsoleReportFormatter.hpp => TextReportFormatter.hpp} (86%) diff --git a/CMakeLists.txt b/CMakeLists.txt index ee4b389..c33e851 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ set(CPP_FILES Src/Resources.rc Src/Utils.cpp Src/VulkanData.cpp - Src/ReportFormatter/ConsoleReportFormatter.cpp + Src/ReportFormatter/TextReportFormatter.cpp Src/ReportFormatter/JSONReportFormatter.cpp Src/ReportFormatter/ReportFormatter.cpp ) @@ -38,7 +38,7 @@ set(HPP_FILES Src/Printer.hpp Src/Utils.hpp Src/VulkanData.hpp - Src/ReportFormatter/ConsoleReportFormatter.hpp + Src/ReportFormatter/TextReportFormatter.hpp Src/ReportFormatter/JSONReportFormatter.hpp Src/ReportFormatter/ReportFormatter.hpp ) diff --git a/README.md b/README.md index 6c1254a..b7b207b 100644 --- a/README.md +++ b/README.md @@ -60,12 +60,10 @@ Options: -h --Help Only print this help (command line syntax). -l --List Only print the list of all adapters. -a --Adapter= Print details of adapter at specified index. - --AllNonSoftware Print details of all (except Software) adapters (default behavior). --AllAdapters Print details of all adapters. -j --JSON Print output in JSON format instead of human-friendly text. - --JSONPrettyPrint Print JSON in human friendly form. (default behavior) --JSONNoPrettyPrint Print JSON in minimal size form. - -o --OutputToFile= Output to specified file. + -o --OutputFile= Output to specified file. -f --Formats Include information about DXGI format capabilities. --MetaCommands Include information about meta commands. -e --Enums Include information about all known enums and their values. diff --git a/Src/Enums.hpp b/Src/Enums.hpp index e044f62..f1b82a5 100644 --- a/Src/Enums.hpp +++ b/Src/Enums.hpp @@ -9,8 +9,6 @@ For more information, see files README.md, LICENSE.txt. */ #pragma once -#include - struct EnumItem { const wchar_t* m_Name; diff --git a/Src/Main.cpp b/Src/Main.cpp index 9caf484..1d15951 100644 --- a/Src/Main.cpp +++ b/Src/Main.cpp @@ -94,7 +94,7 @@ static bool g_ShowAllAdapters = true; static bool g_SkipSoftwareAdapter = true; static bool g_UseJsonOutput = false; static bool g_UseJsonPrettyPrint = true; -static bool g_OutputToFile = false; +static bool g_OutputFile = false; static bool g_PrintFormats = false; static bool g_PrintMetaCommands = false; static bool g_PrintEnums = false; @@ -496,17 +496,17 @@ static void PrintVersionHeader() static void PrintVersionData() { - if (IsOutputConsole()) + if (IsTextOutput()) { PrintVersionHeader(); Printer::PrintNewLine(); Printer::PrintNewLine(); } - ReportScopeObject scope(OutputSpecificString(L"General", L"Header")); + ReportScopeObject scope(SelectString(L"General", L"Header")); ReportFormatter& formatter = ReportFormatter::GetInstance(); - if (IsOutputJson()) + if (IsJsonOutput()) { formatter.AddFieldString(L"Program", L"D3d12info"); formatter.AddFieldString(L"Version", PROGRAM_VERSION); @@ -516,13 +516,13 @@ static void PrintVersionData() } formatter.AddFieldString(L"Generated on", MakeCurrentDate().c_str()); #ifdef USE_PREVIEW_AGILITY_SDK - if (IsOutputJson()) + if (IsJsonOutput()) { formatter.AddFieldBool(L"Using preview Agility SDK", true); } formatter.AddFieldUint32(L"D3D12_PREVIEW_SDK_VERSION", uint32_t(D3D12SDKVersion)); #else - if (IsOutputJson()) + if (IsJsonOutput()) { formatter.AddFieldBool(L"Using preview Agility SDK", false); } @@ -687,9 +687,7 @@ static void EnableExperimentalFeatures() } } - std::wstring enabledFeaturesStr = std::accumulate(enabledFeatures.begin(), enabledFeatures.end(), std::wstring{}, - [](const std::wstring& a, const std::wstring& b) { return a.empty() ? b : a + L"," + b; }); - ReportFormatter::GetInstance().AddFieldString(L"D3D12EnableExperimentalFeatures", enabledFeaturesStr); + ReportFormatter::GetInstance().AddFieldStringArray(L"D3D12EnableExperimentalFeatures", enabledFeatures); } } @@ -855,7 +853,7 @@ static void PrintFormatInformation(ID3D12Device* device) break; } - ReportScopeObjectConditional scope2(OutputSpecificString(name, std::format(L"{}", (size_t)format))); + ReportScopeObjectConditional scope2(SelectString(name, std::format(L"{}", (size_t)format))); if(formatSupportResult == FormatSupportResult::Ok) { @@ -863,14 +861,14 @@ static void PrintFormatInformation(ID3D12Device* device) formatter.AddFieldFlags(L"Support1", formatSupport.Support1, Enum_D3D12_FORMAT_SUPPORT1); formatter.AddFieldFlags(L"Support2", formatSupport.Support2, Enum_D3D12_FORMAT_SUPPORT2); - ReportScopeObjectConditional scope3(IsOutputJson(), L"MultisampleQualityLevels"); + ReportScopeObjectConditional scope3(IsJsonOutput(), L"MultisampleQualityLevels"); msQualityLevels.Format = format; for(msQualityLevels.SampleCount = 1; ; msQualityLevels.SampleCount *= 2) { if(SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &msQualityLevels, UINT(sizeof msQualityLevels))) && msQualityLevels.NumQualityLevels > 0) { - if(IsOutputJson()) + if(IsJsonOutput()) { ReportScopeObject scope4(std::format(L"{}", msQualityLevels.SampleCount)); formatter.AddFieldUint32(L"NumQualityLevels", msQualityLevels.NumQualityLevels); @@ -1383,12 +1381,10 @@ void PrintCommandLineSyntax() PrinterClass::PrintString(L" -h --Help Only print this help (command line syntax).\n"); PrinterClass::PrintString(L" -l --List Only print the list of all adapters.\n"); PrinterClass::PrintString(L" -a --Adapter= Print details of adapter at specified index.\n"); - PrinterClass::PrintString(L" --AllNonSoftware Print details of all (except Software) adapters (default behavior).\n"); PrinterClass::PrintString(L" --AllAdapters Print details of all adapters.\n"); PrinterClass::PrintString(L" -j --JSON Print output in JSON format instead of human-friendly text.\n"); - PrinterClass::PrintString(L" --JSONPrettyPrint Print JSON in human friendly form. (default behavior)\n"); PrinterClass::PrintString(L" --JSONNoPrettyPrint Print JSON in minimal size form.\n"); - PrinterClass::PrintString(L" -o --OutputToFile= Output to specified file.\n"); + PrinterClass::PrintString(L" -o --OutputFile= Output to specified file.\n"); PrinterClass::PrintString(L" -f --Formats Include information about DXGI format capabilities.\n"); PrinterClass::PrintString(L" --MetaCommands Include information about meta commands.\n"); PrinterClass::PrintString(L" -e --Enums Include information about all known enums and their values.\n"); @@ -1618,10 +1614,8 @@ int wmain3(int argc, wchar_t** argv) CMD_LINE_OPT_HELP, CMD_LINE_OPT_LIST, CMD_LINE_OPT_ADAPTER, - CMD_LINE_OPT_ALL_NON_SOFTWARE, CMD_LINE_OPT_ALL_ADAPTERS, CMD_LINE_OPT_JSON, - CMD_LINE_OPT_JSON_PRETTY_PRINT, CMD_LINE_OPT_JSON_NO_PRETTY_PRINT, CMD_LINE_OPT_OUTPUT_TO_FILE, CMD_LINE_OPT_FORMATS, @@ -1641,14 +1635,12 @@ int wmain3(int argc, wchar_t** argv) cmdLineParser.RegisterOpt(CMD_LINE_OPT_LIST, L'l', false); cmdLineParser.RegisterOpt(CMD_LINE_OPT_ADAPTER, L"Adapter", true); cmdLineParser.RegisterOpt(CMD_LINE_OPT_ADAPTER, L'a', true); - cmdLineParser.RegisterOpt(CMD_LINE_OPT_ALL_NON_SOFTWARE, L"AllNonSoftware", false); cmdLineParser.RegisterOpt(CMD_LINE_OPT_ALL_ADAPTERS, L"AllAdapters", false); cmdLineParser.RegisterOpt(CMD_LINE_OPT_JSON, L"JSON", false); cmdLineParser.RegisterOpt(CMD_LINE_OPT_JSON, L'j', false); - cmdLineParser.RegisterOpt(CMD_LINE_OPT_JSON_PRETTY_PRINT, L"JSONPrettyPrint", false); cmdLineParser.RegisterOpt(CMD_LINE_OPT_JSON_NO_PRETTY_PRINT, L"JSONNoPrettyPrint", false); cmdLineParser.RegisterOpt(CMD_LINE_OPT_OUTPUT_TO_FILE, L'o', true); - cmdLineParser.RegisterOpt(CMD_LINE_OPT_OUTPUT_TO_FILE, L"OutputToFile", true); + cmdLineParser.RegisterOpt(CMD_LINE_OPT_OUTPUT_TO_FILE, L"OutputFile", true); cmdLineParser.RegisterOpt(CMD_LINE_OPT_FORMATS, L"Formats", false); cmdLineParser.RegisterOpt(CMD_LINE_OPT_FORMATS, L'f', false); cmdLineParser.RegisterOpt(CMD_LINE_OPT_META_COMMANDS, L"MetaCommands", false); @@ -1680,7 +1672,6 @@ int wmain3(int argc, wchar_t** argv) break; case CMD_LINE_OPT_LIST: if(cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ADAPTER) || - cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ALL_NON_SOFTWARE) || cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ALL_ADAPTERS) || cmdLineParser.IsOptEncountered(CMD_LINE_OPT_WARP)) { @@ -1691,7 +1682,6 @@ int wmain3(int argc, wchar_t** argv) break; case CMD_LINE_OPT_ADAPTER: if(cmdLineParser.IsOptEncountered(CMD_LINE_OPT_LIST) || - cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ALL_NON_SOFTWARE) || cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ALL_ADAPTERS) || cmdLineParser.IsOptEncountered(CMD_LINE_OPT_WARP)) { @@ -1701,23 +1691,9 @@ int wmain3(int argc, wchar_t** argv) g_ShowAllAdapters = false; adapterIndex = _wtoi(cmdLineParser.GetParameter().c_str()); break; - case CMD_LINE_OPT_ALL_NON_SOFTWARE: - if(cmdLineParser.IsOptEncountered(CMD_LINE_OPT_LIST) || - cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ADAPTER) || - cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ALL_ADAPTERS) || - cmdLineParser.IsOptEncountered(CMD_LINE_OPT_WARP)) - { - g_ShowCommandLineSyntaxAndFail = true; - break; - } - g_ShowAllAdapters = true; - g_SkipSoftwareAdapter = true; - adapterIndex = UINT32_MAX; - break; case CMD_LINE_OPT_ALL_ADAPTERS: if(cmdLineParser.IsOptEncountered(CMD_LINE_OPT_LIST) || cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ADAPTER) || - cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ALL_NON_SOFTWARE) || cmdLineParser.IsOptEncountered(CMD_LINE_OPT_WARP)) { g_ShowCommandLineSyntaxAndFail = true; @@ -1730,14 +1706,11 @@ int wmain3(int argc, wchar_t** argv) case CMD_LINE_OPT_JSON: g_UseJsonOutput = true; break; - case CMD_LINE_OPT_JSON_PRETTY_PRINT: - g_UseJsonPrettyPrint = true; - break; case CMD_LINE_OPT_JSON_NO_PRETTY_PRINT: g_UseJsonPrettyPrint = false; break; case CMD_LINE_OPT_OUTPUT_TO_FILE: - g_OutputToFile = true; + g_OutputFile = true; g_OutputFilePath = cmdLineParser.GetParameter(); break; case CMD_LINE_OPT_FORMATS: @@ -1781,7 +1754,6 @@ int wmain3(int argc, wchar_t** argv) case CMD_LINE_OPT_WARP: if(cmdLineParser.IsOptEncountered(CMD_LINE_OPT_LIST) || cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ADAPTER) || - cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ALL_NON_SOFTWARE) || cmdLineParser.IsOptEncountered(CMD_LINE_OPT_ALL_ADAPTERS)) { g_ShowCommandLineSyntaxAndFail = true; @@ -1803,47 +1775,31 @@ int wmain3(int argc, wchar_t** argv) if (g_ShowCommandLineSyntaxAndFail) { - Printer::Initialize(false, {}); + PrinterScope scope(false, {}); PrintCommandLineSyntax(); - Printer::Release(); return PROGRAM_EXIT_ERROR_COMMAND_LINE; } g_PrintAdaptersAsArray = g_ShowAllAdapters || g_UseJsonOutput; - if (g_OutputToFile) - { - if (!Printer::Initialize(true, g_OutputFilePath)) - { - ErrorPrinter::PrintFormat(L"Could not open file for writing: {}\n", std::make_wformat_args(g_OutputFilePath)); - return PROGRAM_EXIT_ERROR_INIT; - } - } - else - { - if (!Printer::Initialize(false, {})) - { - assert(0); - return PROGRAM_EXIT_ERROR_INIT; - } - } + PrinterScope printerScope(g_OutputFile, g_OutputFilePath); - ReportFormatter::Flags flags = ReportFormatter::Flags::None; + ReportFormatter::FLAGS flags = ReportFormatter::FLAGS::FLAG_NONE; if (g_UseJsonOutput) { - flags = flags | ReportFormatter::Flags::UseJson; + flags |= ReportFormatter::FLAGS::FLAG_JSON; } if (g_UseJsonPrettyPrint) { - flags = flags | ReportFormatter::Flags::UseJsonPrettyPrint; + flags |= ReportFormatter::FLAGS::FLAG_JSON_PRETTY_PRINT; } - ReportFormatter::CreateInstance(flags); + ReportFormatterScope formatterScope(flags); if (g_ShowVersionAndQuit) { - if (IsOutputConsole()) + if (IsTextOutput()) { PrintVersionHeader(); } @@ -1851,16 +1807,12 @@ int wmain3(int argc, wchar_t** argv) { PrintVersionData(); } - ReportFormatter::DestroyInstance(); - Printer::Release(); return PROGRAM_EXIT_SUCCESS; } if (g_ShowCommandLineSyntaxAndQuit) { PrintCommandLineSyntax(); - ReportFormatter::DestroyInstance(); - Printer::Release(); return PROGRAM_EXIT_SUCCESS; } @@ -1896,7 +1848,7 @@ int wmain3(int argc, wchar_t** argv) #endif { - ReportScopeObject scope(OutputSpecificString(L"System Info", L"SystemInfo")); + ReportScopeObject scope(SelectString(L"System Info", L"SystemInfo")); if(!g_PureD3D12) { @@ -1933,7 +1885,7 @@ int wmain3(int argc, wchar_t** argv) #endif assert(dxgiFactory != nullptr); - ReportScopeArrayConditional scopeArray(g_PrintAdaptersAsArray, OutputSpecificString(L"Adapter", L"Adapters"), ReportFormatter::ArraySuffix::None); + ReportScopeArrayConditional scopeArray(g_PrintAdaptersAsArray, SelectString(L"Adapter", L"Adapters"), ReportFormatter::ARRAY_SUFFIX_NONE); ReportScopeObjectConditional scopeObject(!g_PrintAdaptersAsArray, L"Adapter"); if(g_ListAdapters) @@ -1953,9 +1905,6 @@ int wmain3(int argc, wchar_t** argv) UnloadLibraries(); #endif - ReportFormatter::DestroyInstance(); - Printer::Release(); - return programResult; } diff --git a/Src/Printer.cpp b/Src/Printer.cpp index 71af1d4..ce6a35f 100644 --- a/Src/Printer.cpp +++ b/Src/Printer.cpp @@ -9,9 +9,6 @@ For more information, see files README.md, LICENSE.txt. */ #include "Printer.hpp" -#include -#include - bool Printer::m_IsInitialized = false; bool Printer::m_WritingToFile = false; std::wostream* Printer::m_Output = nullptr; @@ -55,11 +52,11 @@ void Printer::PrintNewLine() *m_Output << std::endl; } -void Printer::PrintString(std::string_view line) +void Printer::PrintString(const std::string& line) { assert(m_IsInitialized); - *m_Output << line.data(); + *m_Output << line.c_str(); } void Printer::PrintString(std::wstring_view line) @@ -81,6 +78,27 @@ void Printer::PrintFormat(std::wstring_view format, std::wformat_args&& args) PrintString(formatted); } +PrinterScope::PrinterScope(bool writeToFile, std::wstring_view name) +{ + if (!Printer::Initialize(writeToFile, name)) + { + if (writeToFile) + { + std::string narrowName(name.begin(), name.end()); + throw std::runtime_error(std::format("Could not open {} for writing.", narrowName)); + } + else + { + throw std::runtime_error("Unexpected error during output initialization."); + } + } +} + +PrinterScope::~PrinterScope() +{ + Printer::Release(); +} + void ErrorPrinter::PrintFormat(std::string_view format, std::format_args&& args) { std::string formatted = std::vformat(format, args); @@ -93,7 +111,7 @@ void ErrorPrinter::PrintFormat(std::wstring_view format, std::wformat_args&& arg PrintString(formatted); } -void ErrorPrinter::PrintString(std::string_view line) +void ErrorPrinter::PrintString(const std::string& line) { std::cerr << line; } @@ -101,4 +119,4 @@ void ErrorPrinter::PrintString(std::string_view line) void ErrorPrinter::PrintString(std::wstring_view line) { std::wcerr << line; -} +} \ No newline at end of file diff --git a/Src/Printer.hpp b/Src/Printer.hpp index e4ce46d..a55df70 100644 --- a/Src/Printer.hpp +++ b/Src/Printer.hpp @@ -20,7 +20,7 @@ class Printer static void PrintNewLine(); - static void PrintString(std::string_view line); + static void PrintString(const std::string& line); static void PrintString(std::wstring_view line); static void PrintFormat(std::string_view format, std::format_args&& args); @@ -32,10 +32,17 @@ class Printer static std::wostream* m_Output; }; +class PrinterScope +{ +public: + PrinterScope(bool writeToFile, std::wstring_view name); + ~PrinterScope(); +}; + class ErrorPrinter { public: - static void PrintString(std::string_view line); + static void PrintString(const std::string& line); static void PrintString(std::wstring_view line); static void PrintFormat(std::string_view format, std::format_args&& args); diff --git a/Src/ReportFormatter/JSONReportFormatter.cpp b/Src/ReportFormatter/JSONReportFormatter.cpp index 39e90f9..766747e 100644 --- a/Src/ReportFormatter/JSONReportFormatter.cpp +++ b/Src/ReportFormatter/JSONReportFormatter.cpp @@ -11,8 +11,8 @@ For more information, see files README.md, LICENSE.txt. #include "Printer.hpp" -JSONReportFormatter::JSONReportFormatter(Flags flags) - : m_PrettyPrint((flags& Flags::UseJsonPrettyPrint) != Flags::None) +JSONReportFormatter::JSONReportFormatter(FLAGS flags) + : m_PrettyPrint((flags & FLAGS::FLAG_JSON_PRETTY_PRINT) != FLAGS::FLAG_NONE) { Printer::PrintString(L"{"); m_ScopeStack.push({ .ElementCount = 0, .Type = ScopeType::Object }); @@ -36,7 +36,7 @@ void JSONReportFormatter::PushObject(std::wstring_view name) m_ScopeStack.push({ .ElementCount = 0, .Type = ScopeType::Object }); } -void JSONReportFormatter::PushArray(std::wstring_view name, ArraySuffix suffix /* = ArraySuffix::SquareBrackets */) +void JSONReportFormatter::PushArray(std::wstring_view name, ARRAY_SUFFIX suffix /* = ArraySuffix::SquareBrackets */) { assert(!name.empty()); @@ -83,6 +83,26 @@ void JSONReportFormatter::AddFieldString(std::wstring_view name, std::wstring_vi Printer::PrintFormat(m_PrettyPrint ? L"\"{}\": \"{}\"" : L"\"{}\":\"{}\"", std::make_wformat_args(name, value)); } +void JSONReportFormatter::AddFieldStringArray(std::wstring_view name, const std::vector& value) +{ + assert(!name.empty()); + PushNewElement(); + Printer::PrintFormat(m_PrettyPrint ? L"\"{}\": [" : L"\"{}\":[", std::make_wformat_args(name)); + for (size_t i = 0; i < value.size(); ++i) + { + if (i > 0) + { + Printer::PrintString(L","); + } + PrintNewLine(); + PrintIndent(1); + Printer::PrintFormat(L"\"{}\"", std::make_wformat_args(value[i])); + } + PrintNewLine(); + PrintIndent(); + Printer::PrintString(L"]"); +} + void JSONReportFormatter::AddFieldBool(std::wstring_view name, bool value) { assert(!name.empty()); diff --git a/Src/ReportFormatter/JSONReportFormatter.hpp b/Src/ReportFormatter/JSONReportFormatter.hpp index 11fc254..a18b890 100644 --- a/Src/ReportFormatter/JSONReportFormatter.hpp +++ b/Src/ReportFormatter/JSONReportFormatter.hpp @@ -16,15 +16,16 @@ For more information, see files README.md, LICENSE.txt. class JSONReportFormatter final : public ReportFormatter { public: - JSONReportFormatter(Flags flags); + JSONReportFormatter(FLAGS flags); ~JSONReportFormatter(); void PushObject(std::wstring_view name) final; - void PushArray(std::wstring_view name, ArraySuffix suffix = ArraySuffix::SquareBrackets); + void PushArray(std::wstring_view name, ARRAY_SUFFIX suffix = ARRAY_SUFFIX_SQUARE_BRACKETS); void PushArrayItem() final; void PopScope() final; void AddFieldString(std::wstring_view name, std::wstring_view value) final; + void AddFieldStringArray(std::wstring_view name, const std::vector& value) final; void AddFieldBool(std::wstring_view name, bool value); void AddFieldUint32(std::wstring_view name, uint32_t value, std::wstring_view unit = {}) final; void AddFieldUint64(std::wstring_view name, uint64_t value, std::wstring_view unit = {}) final; diff --git a/Src/ReportFormatter/ReportFormatter.cpp b/Src/ReportFormatter/ReportFormatter.cpp index 6852191..4444af8 100644 --- a/Src/ReportFormatter/ReportFormatter.cpp +++ b/Src/ReportFormatter/ReportFormatter.cpp @@ -10,21 +10,21 @@ For more information, see files README.md, LICENSE.txt. #include "ReportFormatter.hpp" #include "JSONReportFormatter.hpp" -#include "ConsoleReportFormatter.hpp" +#include "TextReportFormatter.hpp" static ReportFormatter* s_Instance = nullptr; -static ReportFormatter::Flags s_Flags = ReportFormatter::Flags::None; +static ReportFormatter::FLAGS s_Flags = ReportFormatter::FLAGS::FLAG_NONE; -void ReportFormatter::CreateInstance(Flags flags) +void ReportFormatter::CreateInstance(FLAGS flags) { assert(s_Instance == nullptr); - if ((flags & Flags::UseJson) != Flags::None) + if ((flags & FLAGS::FLAG_JSON) != FLAGS::FLAG_NONE) { s_Instance = new JSONReportFormatter(flags); } else { - s_Instance = new ConsoleReportFormatter(flags); + s_Instance = new TextReportFormatter(flags); } s_Flags = flags; } @@ -42,65 +42,16 @@ ReportFormatter& ReportFormatter::GetInstance() return *s_Instance; } -ReportFormatter::Flags ReportFormatter::GetFlags() +ReportFormatter::FLAGS ReportFormatter::GetFlags() { assert(s_Instance != nullptr); return s_Flags; } -ReportFormatter::Flags operator&(ReportFormatter::Flags a, ReportFormatter::Flags b) +ReportFormatter::FLAGS& operator|=(ReportFormatter::FLAGS& lhs, ReportFormatter::FLAGS rhs) { - return static_cast(static_cast(a) & static_cast(b)); -} - -ReportFormatter::Flags operator|(ReportFormatter::Flags a, ReportFormatter::Flags b) -{ - return static_cast(static_cast(a) | static_cast(b)); -} - -bool operator||(bool a, ReportFormatter::Flags b) -{ - return a || (b != ReportFormatter::Flags::None); -} - -bool operator&&(bool a, ReportFormatter::Flags b) -{ - return a && (b != ReportFormatter::Flags::None); -} - -bool operator!(ReportFormatter::Flags a) -{ - return a == ReportFormatter::Flags::None; -} - -ReportScopeObject::ReportScopeObject(std::wstring_view name) -{ - ReportFormatter::GetInstance().PushObject(name); -} - -ReportScopeObject::~ReportScopeObject() -{ - ReportFormatter::GetInstance().PopScope(); -} - -ReportScopeArray::ReportScopeArray(std::wstring_view name, ReportFormatter::ArraySuffix suffix /*= ReportFormatter::ArraySuffix::SquareBrackets*/) -{ - ReportFormatter::GetInstance().PushArray(name, suffix); -} - -ReportScopeArray::~ReportScopeArray() -{ - ReportFormatter::GetInstance().PopScope(); -} - -ReportScopeArrayItem::ReportScopeArrayItem() -{ - ReportFormatter::GetInstance().PushArrayItem(); -} - -ReportScopeArrayItem::~ReportScopeArrayItem() -{ - ReportFormatter::GetInstance().PopScope(); + lhs = static_cast(static_cast(lhs) | static_cast(rhs)); + return lhs; } ReportScopeObjectConditional::ReportScopeObjectConditional(std::wstring_view name) @@ -134,13 +85,13 @@ void ReportScopeObjectConditional::Enable() } } -ReportScopeArrayConditional::ReportScopeArrayConditional(std::wstring_view name, ReportFormatter::ArraySuffix suffix /*= ReportFormatter::ArraySuffix::SquareBrackets*/) +ReportScopeArrayConditional::ReportScopeArrayConditional(std::wstring_view name, ReportFormatter::ARRAY_SUFFIX suffix /*= ReportFormatter::SquareBrackets*/) : m_Name(name) , m_Suffix(suffix) { } -ReportScopeArrayConditional::ReportScopeArrayConditional(bool enable, std::wstring_view name, ReportFormatter::ArraySuffix suffix /*= ReportFormatter::ArraySuffix::SquareBrackets*/) +ReportScopeArrayConditional::ReportScopeArrayConditional(bool enable, std::wstring_view name, ReportFormatter::ARRAY_SUFFIX suffix /*= ReportFormatter::SquareBrackets*/) : ReportScopeArrayConditional(name, suffix) { if (enable) @@ -195,36 +146,36 @@ void ReportScopeArrayItemConditional::Enable() } } -bool IsOutputConsole() +bool IsTextOutput() { - return (ReportFormatter::GetFlags() & ReportFormatter::Flags::UseJson) == ReportFormatter::Flags::None; + return (ReportFormatter::GetFlags() & ReportFormatter::FLAGS::FLAG_JSON) == ReportFormatter::FLAGS::FLAG_NONE; } -bool IsOutputJson() +bool IsJsonOutput() { - return !IsOutputConsole(); + return !IsTextOutput(); } -std::wstring_view OutputSpecificString(std::wstring_view consoleString, std::wstring_view jsonString) +std::wstring_view SelectString(std::wstring_view textString, std::wstring_view jsonString) { - if ((ReportFormatter::GetFlags() & ReportFormatter::Flags::UseJson) != ReportFormatter::Flags::None) + if (IsJsonOutput()) { return jsonString; } else { - return consoleString; + return textString; } } -std::string_view OutputSpecificString(std::string_view consoleString, std::string_view jsonString) +std::string_view SelectString(std::string_view textString, std::string_view jsonString) { - if ((ReportFormatter::GetFlags() & ReportFormatter::Flags::UseJson) != ReportFormatter::Flags::None) + if (IsJsonOutput()) { return jsonString; } else { - return consoleString; + return textString; } } diff --git a/Src/ReportFormatter/ReportFormatter.hpp b/Src/ReportFormatter/ReportFormatter.hpp index 9d6b90f..ef477e9 100644 --- a/Src/ReportFormatter/ReportFormatter.hpp +++ b/Src/ReportFormatter/ReportFormatter.hpp @@ -10,42 +10,40 @@ For more information, see files README.md, LICENSE.txt. #pragma once -#include -#include - struct EnumItem; class ReportFormatter { public: - enum class Flags : uint32_t + enum FLAGS : uint32_t { - None = 0, - UseJson = 1 << 0, - UseJsonPrettyPrint = 1 << 1 + FLAG_NONE = 0, + FLAG_JSON = 1 << 0, + FLAG_JSON_PRETTY_PRINT = 1 << 1 }; - enum class ArraySuffix + enum ARRAY_SUFFIX { - SquareBrackets, - None + ARRAY_SUFFIX_SQUARE_BRACKETS, + ARRAY_SUFFIX_NONE }; - static void CreateInstance(Flags flags); + static void CreateInstance(FLAGS flags); static void DestroyInstance(); static ReportFormatter& GetInstance(); - static Flags GetFlags(); + static FLAGS GetFlags(); virtual ~ReportFormatter() = default; virtual void PushObject(std::wstring_view name) = 0; - virtual void PushArray(std::wstring_view name, ArraySuffix suffix = ArraySuffix::SquareBrackets) = 0; + virtual void PushArray(std::wstring_view name, ARRAY_SUFFIX suffix = ARRAY_SUFFIX_SQUARE_BRACKETS) = 0; virtual void PushArrayItem() = 0; virtual void PopScope() = 0; // Fields // Strings virtual void AddFieldString(std::wstring_view name, std::wstring_view value) = 0; + virtual void AddFieldStringArray(std::wstring_view name, const std::vector& value) = 0; // Booleans virtual void AddFieldBool(std::wstring_view name, bool value) = 0; // Integers @@ -72,31 +70,64 @@ class ReportFormatter virtual void AddFieldNvidiaImplementationID(std::wstring_view name, uint32_t architectureId, uint32_t implementationId, const EnumItem* architecturePlusImplementationIDEnum) = 0; }; -ReportFormatter::Flags operator&(ReportFormatter::Flags a, ReportFormatter::Flags b); -ReportFormatter::Flags operator|(ReportFormatter::Flags a, ReportFormatter::Flags b); -bool operator||(bool a, ReportFormatter::Flags b); -bool operator&&(bool a, ReportFormatter::Flags b); -bool operator!(ReportFormatter::Flags a); +ReportFormatter::FLAGS& operator|=(ReportFormatter::FLAGS& lhs, ReportFormatter::FLAGS rhs); + +class ReportFormatterScope +{ +public: + ReportFormatterScope(ReportFormatter::FLAGS flags) + { + ReportFormatter::CreateInstance(flags); + } + + ~ReportFormatterScope() + { + ReportFormatter::DestroyInstance(); + } +}; class ReportScopeObject { public: - ReportScopeObject(std::wstring_view name); - ~ReportScopeObject(); + + ReportScopeObject(std::wstring_view name) + { + ReportFormatter::GetInstance().PushObject(name); + } + + ~ReportScopeObject() + { + ReportFormatter::GetInstance().PopScope(); + } }; class ReportScopeArray { public: - ReportScopeArray(std::wstring_view name, ReportFormatter::ArraySuffix suffix = ReportFormatter::ArraySuffix::SquareBrackets); - ~ReportScopeArray(); + + ReportScopeArray(std::wstring_view name, ReportFormatter::ARRAY_SUFFIX suffix = ReportFormatter::ARRAY_SUFFIX_SQUARE_BRACKETS) + { + ReportFormatter::GetInstance().PushArray(name, suffix); + } + + ~ReportScopeArray() + { + ReportFormatter::GetInstance().PopScope(); + } }; class ReportScopeArrayItem { public: - ReportScopeArrayItem(); - ~ReportScopeArrayItem(); + ReportScopeArrayItem() + { + ReportFormatter::GetInstance().PushArrayItem(); + } + + ~ReportScopeArrayItem() + { + ReportFormatter::GetInstance().PopScope(); + } }; class ReportScopeObjectConditional @@ -114,13 +145,13 @@ class ReportScopeObjectConditional class ReportScopeArrayConditional { public: - ReportScopeArrayConditional(std::wstring_view name, ReportFormatter::ArraySuffix suffix = ReportFormatter::ArraySuffix::SquareBrackets); - ReportScopeArrayConditional(bool enable, std::wstring_view name, ReportFormatter::ArraySuffix suffix = ReportFormatter::ArraySuffix::SquareBrackets); + ReportScopeArrayConditional(std::wstring_view name, ReportFormatter::ARRAY_SUFFIX suffix = ReportFormatter::ARRAY_SUFFIX_SQUARE_BRACKETS); + ReportScopeArrayConditional(bool enable, std::wstring_view name, ReportFormatter::ARRAY_SUFFIX suffix = ReportFormatter::ARRAY_SUFFIX_SQUARE_BRACKETS); ~ReportScopeArrayConditional(); void Enable(); private: std::wstring m_Name; - ReportFormatter::ArraySuffix m_Suffix; + ReportFormatter::ARRAY_SUFFIX m_Suffix; bool m_Enabled = false; }; @@ -135,7 +166,7 @@ class ReportScopeArrayItemConditional bool m_Enabled = false; }; -bool IsOutputConsole(); -bool IsOutputJson(); -std::wstring_view OutputSpecificString(std::wstring_view consoleString, std::wstring_view jsonString); -std::string_view OutputSpecificString(std::string_view consoleString, std::string_view jsonString); +bool IsTextOutput(); +bool IsJsonOutput(); +std::wstring_view SelectString(std::wstring_view textString, std::wstring_view jsonString); +std::string_view SelectString(std::string_view textString, std::string_view jsonString); diff --git a/Src/ReportFormatter/ConsoleReportFormatter.cpp b/Src/ReportFormatter/TextReportFormatter.cpp similarity index 62% rename from Src/ReportFormatter/ConsoleReportFormatter.cpp rename to Src/ReportFormatter/TextReportFormatter.cpp index 6defdc9..7d540c6 100644 --- a/Src/ReportFormatter/ConsoleReportFormatter.cpp +++ b/Src/ReportFormatter/TextReportFormatter.cpp @@ -1,425 +1,463 @@ -/* -This file is part of D3d12info project: -https://github.com/sawickiap/D3d12info - -Copyright (c) 2018-2025 Adam Sawicki, https://asawicki.info -License: MIT - -For more information, see files README.md, LICENSE.txt. -*/ -#include "ConsoleReportFormatter.hpp" - -#include "Printer.hpp" -#include "Enums.hpp" - -ConsoleReportFormatter::ConsoleReportFormatter(Flags flags) -{ -} - -ConsoleReportFormatter::~ConsoleReportFormatter() -{ - assert(m_ScopeStack.empty()); - Printer::PrintNewLine(); -} - -void ConsoleReportFormatter::PushObject(std::wstring_view name) -{ - assert(!name.empty()); - - // Need to skip new line when outputting first object - if (!m_SkipNewLine) - { - Printer::PrintNewLine(); - Printer::PrintNewLine(); - } - else - { - m_SkipNewLine = false; - } - - PrintIndent(); - - Printer::PrintString(name); - - PrintDivider(name.size()); - - m_ScopeStack.push({ .Type = ScopeType::Object }); - ++m_IndentLevel; -} - -void ConsoleReportFormatter::PushArray(std::wstring_view name, ArraySuffix suffix /* = ArraySuffix::SquareBrackets */) -{ - assert(!name.empty()); - - m_ScopeStack.push({ .ArrayName = std::wstring(name), .Type = ScopeType::Array, .Suffix = suffix }); -} - -void ConsoleReportFormatter::PushArrayItem() -{ - assert(!m_ScopeStack.empty()); - - ScopeInfo& arrayScope = m_ScopeStack.top(); - - assert(arrayScope.Type == ScopeType::Array); - - Printer::PrintNewLine(); - Printer::PrintNewLine(); - PrintIndent(); - - std::wstring header; - switch (arrayScope.Suffix) - { - case ArraySuffix::SquareBrackets: - header = std::format(L"{}[{}]", arrayScope.ArrayName, arrayScope.ElementCount++); - break; - default: - assert(0); - [[fallthrough]]; - case ArraySuffix::None: - header = std::format(L"{} {}", arrayScope.ArrayName, arrayScope.ElementCount++); - break; - } - - Printer::PrintString(header); - - PrintDivider(header.size()); - - m_ScopeStack.push({ .ElementCount = 0, .Type = ScopeType::Object }); - ++m_IndentLevel; -} - -void ConsoleReportFormatter::PopScope() -{ - assert(!m_ScopeStack.empty()); - ScopeInfo scope = m_ScopeStack.top(); - m_ScopeStack.pop(); - if (scope.Type != ScopeType::Array) - { - --m_IndentLevel; - } -} - -void ConsoleReportFormatter::AddFieldString(std::wstring_view name, std::wstring_view value) -{ - assert(!name.empty()); - assert(!value.empty()); - PushElement(); - Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, value)); -} - -void ConsoleReportFormatter::AddFieldBool(std::wstring_view name, bool value) -{ - assert(!name.empty()); - PushElement(); - const wchar_t* boolStr = value ? L"TRUE" : L"FALSE"; - Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, boolStr)); -} - -void ConsoleReportFormatter::AddFieldUint32(std::wstring_view name, uint32_t value, std::wstring_view unit /*= {}*/) -{ - assert(!name.empty()); - PushElement(); - Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, value)); -} - -void ConsoleReportFormatter::AddFieldUint64(std::wstring_view name, uint64_t value, std::wstring_view unit /*= {}*/) -{ - assert(!name.empty()); - PushElement(); - if (unit.empty()) - { - Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, value)); - } - else - { - Printer::PrintFormat(L"{} = {} {}", std::make_wformat_args(name, value, unit)); - } -} - -void ConsoleReportFormatter::AddFieldSize(std::wstring_view name, uint64_t value) -{ - assert(!name.empty()); - PushElement(); - - const wchar_t* units[] = { L"B", L"KiB", L"MiB", L"GiB", L"TiB" }; - - int selectedUnit = 0; - uint64_t scale = 1; - for (; selectedUnit < ARRAYSIZE(units) - 1; ++selectedUnit) - { - if (value / scale < 1024) - { - break; - } - scale = scale << 10; - } - - if (selectedUnit == 0) - { - Printer::PrintFormat(L"{} = {} {}", std::make_wformat_args(name, value, units[selectedUnit])); - return; - } - else - { - double valueScaled = double(value) / scale; - Printer::PrintFormat(L"{} = {:.2f} {} ({} B)", std::make_wformat_args(name, valueScaled, units[selectedUnit], value)); - } -} - -void ConsoleReportFormatter::AddFieldSizeKilobytes(std::wstring_view name, uint64_t value) -{ - AddFieldSize(name, value * 1024); -} - -void ConsoleReportFormatter::AddFieldHex32(std::wstring_view name, uint32_t value) -{ - assert(!name.empty()); - PushElement(); - Printer::PrintFormat(L"{} = 0x{:X}", std::make_wformat_args(name, value)); -} - -void ConsoleReportFormatter::AddFieldInt32(std::wstring_view name, int32_t value, std::wstring_view unit /*= {}*/) -{ - assert(!name.empty()); - PushElement(); - if (unit.empty()) - { - Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, value)); - } - else - { - Printer::PrintFormat(L"{} = {} {}", std::make_wformat_args(name, value, unit)); - } -} - -void ConsoleReportFormatter::AddFieldFloat(std::wstring_view name, float value, std::wstring_view unit /*= {}*/) -{ - assert(!name.empty()); - PushElement(); - if (unit.empty()) - { - Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, value)); - } - else - { - Printer::PrintFormat(L"{} = {} {}", std::make_wformat_args(name, value, unit)); - } -} - -void ConsoleReportFormatter::AddFieldEnum(std::wstring_view name, uint32_t value, const EnumItem* enumItems) -{ - assert(!name.empty()); - PushElement(); - const wchar_t* enumItemName = FindEnumItemName(value, enumItems); - if (enumItemName == nullptr) - { - enumItemName = L"Unknown"; - } - - Printer::PrintFormat(L"{} = {} (0x{:X})", std::make_wformat_args(name, enumItemName, value)); -} - -void ConsoleReportFormatter::AddFieldEnumSigned(std::wstring_view name, int32_t value, const EnumItem* enumItems) -{ - assert(!name.empty()); - PushElement(); - const wchar_t* enumItemName = FindEnumItemName(value, enumItems); - if (enumItemName == nullptr) - { - enumItemName = L"Unknown"; - } - - Printer::PrintFormat(L"{} = {} ({})", std::make_wformat_args(name, enumItemName, value)); -} - -void ConsoleReportFormatter::AddEnumArray(std::wstring_view name, const uint32_t* values, size_t count, const EnumItem* enumItems) -{ - assert(!name.empty()); - PushElement(); - Printer::PrintFormat(L"{}", std::make_wformat_args(name)); - ++m_IndentLevel; - for (size_t i = 0; i < count; ++i) - { - Printer::PrintNewLine(); - PrintIndent(); - const wchar_t* enumItemName = FindEnumItemName(values[i], enumItems); - if (enumItemName == nullptr) - { - enumItemName = L"Unknown"; - } - Printer::PrintFormat(L"[{}] = {} (0x{:X})", std::make_wformat_args(i, enumItemName, values[i])); - } - --m_IndentLevel; -} - -void ConsoleReportFormatter::AddFieldFlags(std::wstring_view name, uint32_t value, const EnumItem* enumItems) -{ - assert(!name.empty()); - PushElement(); - Printer::PrintFormat(L"{} = 0x{:X}", std::make_wformat_args(name, value)); - - ++m_IndentLevel; - size_t zeroFlagIndex = SIZE_MAX; - for (size_t i = 0; enumItems[i].m_Name != nullptr; ++i) - { - if (enumItems[i].m_Value == 0) - { - zeroFlagIndex = i; - } - else - { - if ((value & enumItems[i].m_Value) != 0) - { - Printer::PrintNewLine(); - PrintIndent(); - Printer::PrintString(enumItems[i].m_Name); - } - } - } - if (value == 0 && zeroFlagIndex != SIZE_MAX) - { - Printer::PrintNewLine(); - PrintIndent(); - Printer::PrintString(enumItems[zeroFlagIndex].m_Name); - } - --m_IndentLevel; -} - -void ConsoleReportFormatter::AddFieldHexBytes(std::wstring_view name, const void* data, size_t byteCount) -{ - std::wstring valStr; - for (size_t i = 0; i < byteCount; ++i) - { - valStr += std::format(L"{:02X}", *((const uint8_t*)data + i)); - } - AddFieldString(name, valStr); -} - -void ConsoleReportFormatter::AddFieldVendorId(std::wstring_view name, uint32_t value) -{ - assert(!name.empty()); - - auto ACPIIDOpt = DecodeACPIID(value); - - if (ACPIIDOpt.has_value()) - { - PushElement(); - auto& ACPIID = ACPIIDOpt.value(); - const wchar_t* enumItemName = FindEnumItemName(value, Enum_VendorId); - if (enumItemName == nullptr) - { - enumItemName = L"Unknown"; - } - - Printer::PrintFormat(L"{} = {} \"{}\" (0x{:X})", std::make_wformat_args(name, enumItemName, ACPIID, value)); - } - else - { - AddFieldEnum(name, value, Enum_VendorId); - } - -} - -void ConsoleReportFormatter::AddFieldSubsystemId(std::wstring_view name, uint32_t value) -{ - assert(!name.empty()); - PushElement(); - - const wchar_t* enumItemName = FindEnumItemName(value & 0xFFFF, Enum_SubsystemVendorId); - if (enumItemName == nullptr) - { - enumItemName = L"Unknown"; - } - - Printer::PrintFormat(L"{} = {} (0x{:X})", std::make_wformat_args(name, enumItemName, value)); -} - -void ConsoleReportFormatter::AddFieldMicrosoftVersion(std::wstring_view name, uint64_t value) -{ - assert(!name.empty()); - PushElement(); - uint64_t major = value >> 48; - uint64_t minor = (value >> 32) & 0xFFFF; - uint64_t build = (value >> 16) & 0xFFFF; - uint64_t revision = value & 0xFFFF; - Printer::PrintFormat(L"{} = {}.{}.{}.{}", std::make_wformat_args(name, major, minor, build, revision)); -} - -void ConsoleReportFormatter::AddFieldAMDVersion(std::wstring_view name, uint64_t value) -{ - assert(!name.empty()); - PushElement(); - uint64_t major = value >> 22; - uint64_t minor = (value >> 12) & 0b11'1111'1111; - uint64_t patch = value & 0b1111'1111'1111; - Printer::PrintFormat(L"{} = {}.{}.{}", std::make_wformat_args(name, major, minor, patch)); -} - -void ConsoleReportFormatter::AddFieldNvidiaImplementationID(std::wstring_view name, uint32_t architectureId, uint32_t implementationId, const EnumItem* architecturePlusImplementationIDEnum) -{ - // Prints only implementationId as the numerical value, but searches enum - // using architectureId + implementationId. - - assert(!name.empty()); - PushElement(); - - const wchar_t* enumItemName = FindEnumItemName(architectureId + implementationId, - architecturePlusImplementationIDEnum); - if (enumItemName == nullptr) - { - enumItemName = L"Unknown"; - } - - Printer::PrintFormat(L"{} = {} (0x{:X})", std::make_wformat_args(name, enumItemName, implementationId)); -} - -void ConsoleReportFormatter::PrintIndent() const -{ - Printer::PrintString(std::wstring(INDENT_SIZE * m_IndentLevel, INDENT_CHAR)); -} - -void ConsoleReportFormatter::PushElement() -{ - m_ScopeStack.top().ElementCount++; - Printer::PrintNewLine(); - PrintIndent(); -} - -void ConsoleReportFormatter::PrintDivider(size_t size) -{ - Printer::PrintNewLine(); - PrintIndent(); - wchar_t dividerChar; - - switch (m_IndentLevel) - { - case 0: - dividerChar = L'='; - break; - default: - dividerChar = L'-'; - break; - } - - Printer::PrintString(std::wstring(size, dividerChar)); -} - -std::optional ConsoleReportFormatter::DecodeACPIID(uint32_t value) -{ - if (value <= 0xFFFF) - { - return std::nullopt; - } - - std::wstring result; - result.resize(4); - - for (uint32_t i = 0; i < 4; ++i) - { - const uint8_t charValue = (uint8_t)(value >> (i * 8)); - if (charValue < 32 || charValue > 126) - return std::nullopt; - result[i] = (wchar_t)charValue; - } - return result; -} +/* +This file is part of D3d12info project: +https://github.com/sawickiap/D3d12info + +Copyright (c) 2018-2025 Adam Sawicki, https://asawicki.info +License: MIT + +For more information, see files README.md, LICENSE.txt. +*/ +#include "TextReportFormatter.hpp" + +#include "Printer.hpp" +#include "Enums.hpp" + +TextReportFormatter::TextReportFormatter(FLAGS flags) +{ +} + +TextReportFormatter::~TextReportFormatter() +{ + assert(m_ScopeStack.empty()); + Printer::PrintNewLine(); +} + +void TextReportFormatter::PushObject(std::wstring_view name) +{ + assert(!name.empty()); + + // Need to skip new line when outputting first object + if (!m_SkipNewLine) + { + Printer::PrintNewLine(); + Printer::PrintNewLine(); + } + else + { + m_SkipNewLine = false; + } + + PrintIndent(); + + Printer::PrintString(name); + Printer::PrintString(L":"); + + PrintDivider(name.size() + 1); + + m_ScopeStack.push({ .Type = ScopeType::Object }); + ++m_IndentLevel; +} + +void TextReportFormatter::PushArray(std::wstring_view name, ARRAY_SUFFIX suffix /* = ArraySuffix::SquareBrackets */) +{ + assert(!name.empty()); + + m_ScopeStack.push({ .ArrayName = std::wstring(name), .Type = ScopeType::Array, .Suffix = suffix }); +} + +void TextReportFormatter::PushArrayItem() +{ + assert(!m_ScopeStack.empty()); + + ScopeInfo& arrayScope = m_ScopeStack.top(); + + assert(arrayScope.Type == ScopeType::Array); + + Printer::PrintNewLine(); + Printer::PrintNewLine(); + PrintIndent(); + + std::wstring header; + switch (arrayScope.Suffix) + { + case ARRAY_SUFFIX_SQUARE_BRACKETS: + header = std::format(L"{}[{}]:", arrayScope.ArrayName, arrayScope.ElementCount++); + break; + default: + assert(0); + [[fallthrough]]; + case ARRAY_SUFFIX_NONE: + header = std::format(L"{} {}:", arrayScope.ArrayName, arrayScope.ElementCount++); + break; + } + + Printer::PrintString(header); + + PrintDivider(header.size()); + + m_ScopeStack.push({ .ElementCount = 0, .Type = ScopeType::Object }); + ++m_IndentLevel; +} + +void TextReportFormatter::PopScope() +{ + assert(!m_ScopeStack.empty()); + ScopeInfo scope = m_ScopeStack.top(); + m_ScopeStack.pop(); + if (scope.Type != ScopeType::Array) + { + --m_IndentLevel; + } +} + +void TextReportFormatter::AddFieldString(std::wstring_view name, std::wstring_view value) +{ + assert(!name.empty()); + assert(!value.empty()); + PushElement(); + Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, value)); +} + +void TextReportFormatter::AddFieldStringArray(std::wstring_view name, const std::vector& value) +{ + assert(!name.empty()); + + Printer::PrintNewLine(); + PushElement(); + Printer::PrintString(name); + Printer::PrintString(L":"); + PrintDivider(name.size() + 1); + + ++m_IndentLevel; + for (const auto& element : value) + { + Printer::PrintNewLine(); + PrintIndent(); + Printer::PrintString(element); + } + --m_IndentLevel; +} + +void TextReportFormatter::AddFieldBool(std::wstring_view name, bool value) +{ + assert(!name.empty()); + PushElement(); + const wchar_t* boolStr = value ? L"TRUE" : L"FALSE"; + Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, boolStr)); +} + +void TextReportFormatter::AddFieldUint32(std::wstring_view name, uint32_t value, std::wstring_view unit /*= {}*/) +{ + assert(!name.empty()); + PushElement(); + Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, value)); +} + +void TextReportFormatter::AddFieldUint64(std::wstring_view name, uint64_t value, std::wstring_view unit /*= {}*/) +{ + assert(!name.empty()); + PushElement(); + if (unit.empty()) + { + Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, value)); + } + else + { + Printer::PrintFormat(L"{} = {} {}", std::make_wformat_args(name, value, unit)); + } +} + +void TextReportFormatter::AddFieldSize(std::wstring_view name, uint64_t value) +{ + assert(!name.empty()); + PushElement(); + + const wchar_t* units[] = { L"B", L"KiB", L"MiB", L"GiB", L"TiB" }; + + int selectedUnit = 0; + uint64_t scale = 1; + for (; selectedUnit < ARRAYSIZE(units) - 1; ++selectedUnit) + { + if (value / scale < 1024) + { + break; + } + scale = scale << 10; + } + + if (selectedUnit == 0) + { + Printer::PrintFormat(L"{} = {} {}", std::make_wformat_args(name, value, units[selectedUnit])); + return; + } + else + { + double valueScaled = double(value) / scale; + Printer::PrintFormat(L"{} = {:.2f} {} ({} B)", std::make_wformat_args(name, valueScaled, units[selectedUnit], value)); + } +} + +void TextReportFormatter::AddFieldSizeKilobytes(std::wstring_view name, uint64_t value) +{ + AddFieldSize(name, value * 1024); +} + +void TextReportFormatter::AddFieldHex32(std::wstring_view name, uint32_t value) +{ + assert(!name.empty()); + PushElement(); + Printer::PrintFormat(L"{} = 0x{:X}", std::make_wformat_args(name, value)); +} + +void TextReportFormatter::AddFieldInt32(std::wstring_view name, int32_t value, std::wstring_view unit /*= {}*/) +{ + assert(!name.empty()); + PushElement(); + if (unit.empty()) + { + Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, value)); + } + else + { + Printer::PrintFormat(L"{} = {} {}", std::make_wformat_args(name, value, unit)); + } +} + +void TextReportFormatter::AddFieldFloat(std::wstring_view name, float value, std::wstring_view unit /*= {}*/) +{ + assert(!name.empty()); + PushElement(); + if (unit.empty()) + { + Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, value)); + } + else + { + Printer::PrintFormat(L"{} = {} {}", std::make_wformat_args(name, value, unit)); + } +} + +void TextReportFormatter::AddFieldEnum(std::wstring_view name, uint32_t value, const EnumItem* enumItems) +{ + assert(!name.empty()); + PushElement(); + const wchar_t* enumItemName = FindEnumItemName(value, enumItems); + if (enumItemName != nullptr) + { + Printer::PrintFormat(L"{} = {} (0x{:X})", std::make_wformat_args(name, enumItemName, value)); + } + else + { + Printer::PrintFormat(L"{} = 0x{:X}", std::make_wformat_args(name, value)); + } +} + +void TextReportFormatter::AddFieldEnumSigned(std::wstring_view name, int32_t value, const EnumItem* enumItems) +{ + assert(!name.empty()); + PushElement(); + const wchar_t* enumItemName = FindEnumItemName(value, enumItems); + if (enumItemName != nullptr) + { + Printer::PrintFormat(L"{} = {} ({})", std::make_wformat_args(name, enumItemName, value)); + } + else + { + Printer::PrintFormat(L"{} = {}", std::make_wformat_args(name, value)); + } + +} + +void TextReportFormatter::AddEnumArray(std::wstring_view name, const uint32_t* values, size_t count, const EnumItem* enumItems) +{ + assert(!name.empty()); + + Printer::PrintNewLine(); + PushElement(); + Printer::PrintString(name); + Printer::PrintString(L":"); + PrintDivider(name.size() + 1); + + ++m_IndentLevel; + for (size_t i = 0; i < count; ++i) + { + Printer::PrintNewLine(); + PrintIndent(); + const wchar_t* enumItemName = FindEnumItemName(values[i], enumItems); + if (enumItemName != nullptr) + { + Printer::PrintFormat(L"[{}] = {} (0x{:X})", std::make_wformat_args(i, enumItemName, values[i])); + } + else + { + Printer::PrintFormat(L"[{}] = 0x{:X}", std::make_wformat_args(i, values[i])); + } + } + --m_IndentLevel; +} + +void TextReportFormatter::AddFieldFlags(std::wstring_view name, uint32_t value, const EnumItem* enumItems) +{ + assert(!name.empty()); + PushElement(); + Printer::PrintFormat(L"{} = 0x{:X}", std::make_wformat_args(name, value)); + + ++m_IndentLevel; + size_t zeroFlagIndex = SIZE_MAX; + for (size_t i = 0; enumItems[i].m_Name != nullptr; ++i) + { + if (enumItems[i].m_Value == 0) + { + zeroFlagIndex = i; + } + else + { + if ((value & enumItems[i].m_Value) != 0) + { + Printer::PrintNewLine(); + PrintIndent(); + Printer::PrintString(enumItems[i].m_Name); + } + } + } + if (value == 0 && zeroFlagIndex != SIZE_MAX) + { + Printer::PrintNewLine(); + PrintIndent(); + Printer::PrintString(enumItems[zeroFlagIndex].m_Name); + } + --m_IndentLevel; +} + +void TextReportFormatter::AddFieldHexBytes(std::wstring_view name, const void* data, size_t byteCount) +{ + std::wstring valStr; + for (size_t i = 0; i < byteCount; ++i) + { + valStr += std::format(L"{:02X}", *((const uint8_t*)data + i)); + } + AddFieldString(name, valStr); +} + +void TextReportFormatter::AddFieldVendorId(std::wstring_view name, uint32_t value) +{ + assert(!name.empty()); + + auto ACPIIDOpt = DecodeACPIID(value); + + if (ACPIIDOpt.has_value()) + { + PushElement(); + auto& ACPIID = ACPIIDOpt.value(); + const wchar_t* enumItemName = FindEnumItemName(value, Enum_VendorId); + if (enumItemName == nullptr) + { + enumItemName = L"Unknown"; + } + + Printer::PrintFormat(L"{} = {} \"{}\" (0x{:X})", std::make_wformat_args(name, enumItemName, ACPIID, value)); + } + else + { + AddFieldEnum(name, value, Enum_VendorId); + } + +} + +void TextReportFormatter::AddFieldSubsystemId(std::wstring_view name, uint32_t value) +{ + assert(!name.empty()); + PushElement(); + + const wchar_t* enumItemName = FindEnumItemName(value & 0xFFFF, Enum_SubsystemVendorId); + if (enumItemName != nullptr) + { + Printer::PrintFormat(L"{} = {} (0x{:X})", std::make_wformat_args(name, enumItemName, value)); + } + else + { + Printer::PrintFormat(L"{} = 0x{:X}", std::make_wformat_args(name, value)); + } + +} + +void TextReportFormatter::AddFieldMicrosoftVersion(std::wstring_view name, uint64_t value) +{ + assert(!name.empty()); + PushElement(); + uint64_t major = value >> 48; + uint64_t minor = (value >> 32) & 0xFFFF; + uint64_t build = (value >> 16) & 0xFFFF; + uint64_t revision = value & 0xFFFF; + Printer::PrintFormat(L"{} = {}.{}.{}.{}", std::make_wformat_args(name, major, minor, build, revision)); +} + +void TextReportFormatter::AddFieldAMDVersion(std::wstring_view name, uint64_t value) +{ + assert(!name.empty()); + PushElement(); + uint64_t major = value >> 22; + uint64_t minor = (value >> 12) & 0b11'1111'1111; + uint64_t patch = value & 0b1111'1111'1111; + Printer::PrintFormat(L"{} = {}.{}.{}", std::make_wformat_args(name, major, minor, patch)); +} + +void TextReportFormatter::AddFieldNvidiaImplementationID(std::wstring_view name, uint32_t architectureId, uint32_t implementationId, const EnumItem* architecturePlusImplementationIDEnum) +{ + // Prints only implementationId as the numerical value, but searches enum + // using architectureId + implementationId. + + assert(!name.empty()); + PushElement(); + + const wchar_t* enumItemName = FindEnumItemName(architectureId + implementationId, + architecturePlusImplementationIDEnum); + if (enumItemName == nullptr) + { + enumItemName = L"Unknown"; + } + + Printer::PrintFormat(L"{} = {} (0x{:X})", std::make_wformat_args(name, enumItemName, implementationId)); +} + +void TextReportFormatter::PrintIndent() const +{ + int effectiveIndentLevel = std::max(m_IndentLevel - 1, 0); + Printer::PrintString(std::wstring(INDENT_SIZE * effectiveIndentLevel, INDENT_CHAR)); +} + +void TextReportFormatter::PushElement() +{ + m_ScopeStack.top().ElementCount++; + Printer::PrintNewLine(); + PrintIndent(); +} + +void TextReportFormatter::PrintDivider(size_t size) +{ + Printer::PrintNewLine(); + PrintIndent(); + wchar_t dividerChar; + + switch (m_IndentLevel) + { + case 0: + dividerChar = L'='; + break; + default: + dividerChar = L'-'; + break; + } + + Printer::PrintString(std::wstring(size, dividerChar)); +} + +std::optional TextReportFormatter::DecodeACPIID(uint32_t value) +{ + if (value <= 0xFFFF) + { + return std::nullopt; + } + + std::wstring result; + result.resize(4); + + for (uint32_t i = 0; i < 4; ++i) + { + const uint8_t charValue = (uint8_t)(value >> (i * 8)); + if (charValue < 32 || charValue > 126) + return std::nullopt; + result[i] = (wchar_t)charValue; + } + return result; +} diff --git a/Src/ReportFormatter/ConsoleReportFormatter.hpp b/Src/ReportFormatter/TextReportFormatter.hpp similarity index 86% rename from Src/ReportFormatter/ConsoleReportFormatter.hpp rename to Src/ReportFormatter/TextReportFormatter.hpp index c576596..28c14db 100644 --- a/Src/ReportFormatter/ConsoleReportFormatter.hpp +++ b/Src/ReportFormatter/TextReportFormatter.hpp @@ -1,73 +1,72 @@ -/* -This file is part of D3d12info project: -https://github.com/sawickiap/D3d12info - -Copyright (c) 2018-2025 Adam Sawicki, https://asawicki.info -License: MIT - -For more information, see files README.md, LICENSE.txt. -*/ - -#pragma once - -#include "ReportFormatter.hpp" -#include -#include - -class ConsoleReportFormatter final : public ReportFormatter -{ -public: - ConsoleReportFormatter(Flags flags); - ~ConsoleReportFormatter(); - - void PushObject(std::wstring_view name) final; - void PushArray(std::wstring_view name, ArraySuffix suffix = ArraySuffix::SquareBrackets); - void PushArrayItem() final; - void PopScope() final; - - void AddFieldString(std::wstring_view name, std::wstring_view value) final; - void AddFieldBool(std::wstring_view name, bool value); - void AddFieldUint32(std::wstring_view name, uint32_t value, std::wstring_view unit = {}) final; - void AddFieldUint64(std::wstring_view name, uint64_t value, std::wstring_view unit = {}) final; - void AddFieldSize(std::wstring_view name, uint64_t value) final; - void AddFieldSizeKilobytes(std::wstring_view name, uint64_t value) final; - void AddFieldHex32(std::wstring_view name, uint32_t value) final; - void AddFieldInt32(std::wstring_view name, int32_t value, std::wstring_view unit = {}) final; - void AddFieldFloat(std::wstring_view name, float value, std::wstring_view unit = {}) final; - void AddFieldEnum(std::wstring_view name, uint32_t value, const EnumItem* enumItems) final; - void AddFieldEnumSigned(std::wstring_view name, int32_t value, const EnumItem* enumItems) final; - void AddEnumArray(std::wstring_view name, const uint32_t* values, size_t count, const EnumItem* enumItems) final; - void AddFieldFlags(std::wstring_view name, uint32_t value, const EnumItem* enumItems) final; - void AddFieldHexBytes(std::wstring_view name, const void* data, size_t byteCount) final; - void AddFieldVendorId(std::wstring_view name, uint32_t value) final; - void AddFieldSubsystemId(std::wstring_view name, uint32_t value) final; - void AddFieldMicrosoftVersion(std::wstring_view name, uint64_t value) final; - void AddFieldAMDVersion(std::wstring_view name, uint64_t value) final; - void AddFieldNvidiaImplementationID(std::wstring_view name, uint32_t architectureId, uint32_t implementationId, const EnumItem* architecturePlusImplementationIDEnum) final; - -private: - static constexpr size_t INDENT_SIZE = 4; - static constexpr wchar_t INDENT_CHAR = L' '; - - enum class ScopeType - { - Object, - Array - }; - struct ScopeInfo - { - std::wstring ArrayName; - size_t ElementCount = 0; - ScopeType Type; - ArraySuffix Suffix; - }; - std::stack m_ScopeStack; - uint32_t m_IndentLevel = 0; - bool m_SkipNewLine = true; - - void PrintIndent() const; - void PushElement(); - void PrintDivider(size_t size); - - static std::optional DecodeACPIID(uint32_t value); -}; +/* +This file is part of D3d12info project: +https://github.com/sawickiap/D3d12info + +Copyright (c) 2018-2025 Adam Sawicki, https://asawicki.info +License: MIT + +For more information, see files README.md, LICENSE.txt. +*/ + +#pragma once + +#include "ReportFormatter.hpp" + +class TextReportFormatter final : public ReportFormatter +{ +public: + TextReportFormatter(FLAGS flags); + ~TextReportFormatter(); + + void PushObject(std::wstring_view name) final; + void PushArray(std::wstring_view name, ARRAY_SUFFIX suffix = ARRAY_SUFFIX_SQUARE_BRACKETS); + void PushArrayItem() final; + void PopScope() final; + + void AddFieldString(std::wstring_view name, std::wstring_view value) final; + void AddFieldStringArray(std::wstring_view name, const std::vector& value) final; + void AddFieldBool(std::wstring_view name, bool value); + void AddFieldUint32(std::wstring_view name, uint32_t value, std::wstring_view unit = {}) final; + void AddFieldUint64(std::wstring_view name, uint64_t value, std::wstring_view unit = {}) final; + void AddFieldSize(std::wstring_view name, uint64_t value) final; + void AddFieldSizeKilobytes(std::wstring_view name, uint64_t value) final; + void AddFieldHex32(std::wstring_view name, uint32_t value) final; + void AddFieldInt32(std::wstring_view name, int32_t value, std::wstring_view unit = {}) final; + void AddFieldFloat(std::wstring_view name, float value, std::wstring_view unit = {}) final; + void AddFieldEnum(std::wstring_view name, uint32_t value, const EnumItem* enumItems) final; + void AddFieldEnumSigned(std::wstring_view name, int32_t value, const EnumItem* enumItems) final; + void AddEnumArray(std::wstring_view name, const uint32_t* values, size_t count, const EnumItem* enumItems) final; + void AddFieldFlags(std::wstring_view name, uint32_t value, const EnumItem* enumItems) final; + void AddFieldHexBytes(std::wstring_view name, const void* data, size_t byteCount) final; + void AddFieldVendorId(std::wstring_view name, uint32_t value) final; + void AddFieldSubsystemId(std::wstring_view name, uint32_t value) final; + void AddFieldMicrosoftVersion(std::wstring_view name, uint64_t value) final; + void AddFieldAMDVersion(std::wstring_view name, uint64_t value) final; + void AddFieldNvidiaImplementationID(std::wstring_view name, uint32_t architectureId, uint32_t implementationId, const EnumItem* architecturePlusImplementationIDEnum) final; + +private: + static constexpr size_t INDENT_SIZE = 4; + static constexpr wchar_t INDENT_CHAR = L' '; + + enum class ScopeType + { + Object, + Array + }; + struct ScopeInfo + { + std::wstring ArrayName; + size_t ElementCount = 0; + ScopeType Type; + ARRAY_SUFFIX Suffix; + }; + std::stack m_ScopeStack; + int m_IndentLevel = 0; + bool m_SkipNewLine = true; + + void PrintIndent() const; + void PushElement(); + void PrintDivider(size_t size); + + static std::optional DecodeACPIID(uint32_t value); +}; diff --git a/Src/pch.hpp b/Src/pch.hpp index 209904c..84faa00 100644 --- a/Src/pch.hpp +++ b/Src/pch.hpp @@ -31,23 +31,29 @@ For more information, see files README.md, LICENSE.txt. #include // For StringFromGUID2 #include // for ComPtr -#include +#include #include -#include -#include #include #include -#include -#include -#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include -#include #include +#include +#include #include #include -#include #include +#include using std::string; using std::wstring; From 90c8b94ac703e51601e5c29481be5b97f79c1165 Mon Sep 17 00:00:00 2001 From: Dmytro Bulatov Date: Fri, 28 Feb 2025 05:49:00 +0900 Subject: [PATCH 5/6] Removed rapidjson submodule as it is no longer used --- .gitmodules | 3 --- CMakeLists.txt | 8 -------- README.md | 2 -- Src/ThirdParty/rapidjson | 1 - 4 files changed, 14 deletions(-) delete mode 160000 Src/ThirdParty/rapidjson diff --git a/.gitmodules b/.gitmodules index cb83ff7..8332ce1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "Src/ThirdParty/gpudetect"] path = Src/ThirdParty/gpudetect url = https://github.com/GameTechDev/gpudetect.git -[submodule "Src/ThirdParty/rapidjson"] - path = Src/ThirdParty/rapidjson - url = https://github.com/Tencent/rapidjson.git [submodule "Src/ThirdParty/nvapi"] path = Src/ThirdParty/nvapi url = https://github.com/NVIDIA/nvapi.git diff --git a/CMakeLists.txt b/CMakeLists.txt index c33e851..5784397 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,13 +43,8 @@ set(HPP_FILES Src/ReportFormatter/ReportFormatter.hpp ) -set(RAPIDJSON_NATVIS_FILE "Src/ThirdParty/rapidjson/contrib/natvis/rapidjson.natvis") set(INTEL_GPUDETECT_CFG_FILE "Src/ThirdParty/gpudetect/IntelGfx.cfg") -if(NOT EXISTS "${PROJECT_SOURCE_DIR}/Src/ThirdParty/rapidjson/include/rapidjson/rapidjson.h") - message(FATAL_ERROR "rapidjson library not found. This is likely due to missing submodule. Please initialize submodules.") -endif() - option(ENABLE_AGS "Enables usage of AMD GPU Services (AGS) library." ON) if(ENABLE_AGS) if(EXISTS "${PROJECT_SOURCE_DIR}/Src/ThirdParty/AGS_SDK/ags_lib/inc/amd_ags.h") @@ -123,9 +118,6 @@ function(add_my_executable USE_PREVIEW_AGILITY_SDK) target_compile_definitions(${EXE_NAME} PRIVATE UNICODE _UNICODE) target_precompile_headers(${EXE_NAME} PRIVATE "Src/pch.hpp") - target_sources(${EXE_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/${RAPIDJSON_NATVIS_FILE}") - source_group("ThirdParty" FILES ${RAPIDJSON_NATVIS_FILE}) - if(USE_PREVIEW_AGILITY_SDK) target_compile_definitions(${EXE_NAME} PRIVATE USE_PREVIEW_AGILITY_SDK=1) set(AGILITY_SDK_DIRECTORY "${PROJECT_SOURCE_DIR}/Src/ThirdParty/microsoft.direct3d.d3d12.1.716.0-preview") diff --git a/README.md b/README.md index b7b207b..cb4935d 100644 --- a/README.md +++ b/README.md @@ -90,8 +90,6 @@ It uses following thirt-party libraries: - **[DirectX 12 Agility SDK](https://devblogs.microsoft.com/directx/directx12agility/)** - latest API to Direct3D, by Microsoft. - Embedded in directory: Src\ThirdParty\microsoft.direct3d.d3d12.* -- **[RapidJSON](https://rapidjson.org/)** - a fast JSON parser/generator, by Tencent. License: MIT. - - Linked via submodule. - **[AMD GPU Services](https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK)** - custom vendor extensions to graphics APIs by AMD. - Linked via submodule. - Optional, controlled by Cmake variable `ENABLE_AGS` - on by default. diff --git a/Src/ThirdParty/rapidjson b/Src/ThirdParty/rapidjson deleted file mode 160000 index 24b5e7a..0000000 --- a/Src/ThirdParty/rapidjson +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 24b5e7a8b27f42fa16b96fc70aade9106cf7102f From 3a67fcb398495da6bb6ce4c738a95aa3cc3388c4 Mon Sep 17 00:00:00 2001 From: Dmytro Bulatov Date: Fri, 28 Feb 2025 06:00:05 +0900 Subject: [PATCH 6/6] Renamed JsonNoPrettyPrint to MinimizeJson --- README.md | 2 +- Src/Main.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index cb4935d..10206c0 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ Options: -a --Adapter= Print details of adapter at specified index. --AllAdapters Print details of all adapters. -j --JSON Print output in JSON format instead of human-friendly text. - --JSONNoPrettyPrint Print JSON in minimal size form. + --MinimizeJson Print JSON in minimal size form. -o --OutputFile= Output to specified file. -f --Formats Include information about DXGI format capabilities. --MetaCommands Include information about meta commands. diff --git a/Src/Main.cpp b/Src/Main.cpp index 1d15951..cb4a28f 100644 --- a/Src/Main.cpp +++ b/Src/Main.cpp @@ -1383,7 +1383,7 @@ void PrintCommandLineSyntax() PrinterClass::PrintString(L" -a --Adapter= Print details of adapter at specified index.\n"); PrinterClass::PrintString(L" --AllAdapters Print details of all adapters.\n"); PrinterClass::PrintString(L" -j --JSON Print output in JSON format instead of human-friendly text.\n"); - PrinterClass::PrintString(L" --JSONNoPrettyPrint Print JSON in minimal size form.\n"); + PrinterClass::PrintString(L" --MinimizeJson Print JSON in minimal size form.\n"); PrinterClass::PrintString(L" -o --OutputFile= Output to specified file.\n"); PrinterClass::PrintString(L" -f --Formats Include information about DXGI format capabilities.\n"); PrinterClass::PrintString(L" --MetaCommands Include information about meta commands.\n"); @@ -1616,7 +1616,7 @@ int wmain3(int argc, wchar_t** argv) CMD_LINE_OPT_ADAPTER, CMD_LINE_OPT_ALL_ADAPTERS, CMD_LINE_OPT_JSON, - CMD_LINE_OPT_JSON_NO_PRETTY_PRINT, + CMD_LINE_OPT_MINIMIZE_JSON, CMD_LINE_OPT_OUTPUT_TO_FILE, CMD_LINE_OPT_FORMATS, CMD_LINE_OPT_META_COMMANDS, @@ -1638,7 +1638,7 @@ int wmain3(int argc, wchar_t** argv) cmdLineParser.RegisterOpt(CMD_LINE_OPT_ALL_ADAPTERS, L"AllAdapters", false); cmdLineParser.RegisterOpt(CMD_LINE_OPT_JSON, L"JSON", false); cmdLineParser.RegisterOpt(CMD_LINE_OPT_JSON, L'j', false); - cmdLineParser.RegisterOpt(CMD_LINE_OPT_JSON_NO_PRETTY_PRINT, L"JSONNoPrettyPrint", false); + cmdLineParser.RegisterOpt(CMD_LINE_OPT_MINIMIZE_JSON, L"MinimizeJson", false); cmdLineParser.RegisterOpt(CMD_LINE_OPT_OUTPUT_TO_FILE, L'o', true); cmdLineParser.RegisterOpt(CMD_LINE_OPT_OUTPUT_TO_FILE, L"OutputFile", true); cmdLineParser.RegisterOpt(CMD_LINE_OPT_FORMATS, L"Formats", false); @@ -1706,7 +1706,7 @@ int wmain3(int argc, wchar_t** argv) case CMD_LINE_OPT_JSON: g_UseJsonOutput = true; break; - case CMD_LINE_OPT_JSON_NO_PRETTY_PRINT: + case CMD_LINE_OPT_MINIMIZE_JSON: g_UseJsonPrettyPrint = false; break; case CMD_LINE_OPT_OUTPUT_TO_FILE: