diff options
Diffstat (limited to 'indra/newview/llviewerstats.cpp')
-rw-r--r-- | indra/newview/llviewerstats.cpp | 159 |
1 files changed, 118 insertions, 41 deletions
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 1607296194..490cadee5c 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -67,6 +67,53 @@ #include "lluiusage.h" #include "lltranslate.h" +// "Minimal Vulkan" to get max API Version + +// Calls + #if defined(_WIN32) + #define VKAPI_ATTR + #define VKAPI_CALL __stdcall + #define VKAPI_PTR VKAPI_CALL + #else + #define VKAPI_ATTR + #define VKAPI_CALL + #define VKAPI_PTR + #endif // _WIN32 + +// Macros + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // <variant> <-------major-------><-----------minor-----------> <--------------patch--------------> + // 0x7 0x7F 0x3FF 0xFFF + #define VK_API_VERSION_MAJOR( version) (((uint32_t)(version) >> 22) & 0x07FU) // 7 bits + #define VK_API_VERSION_MINOR( version) (((uint32_t)(version) >> 12) & 0x3FFU) // 10 bits + #define VK_API_VERSION_PATCH( version) (((uint32_t)(version) ) & 0xFFFU) // 12 bits + #define VK_API_VERSION_VARIANT(version) (((uint32_t)(version) >> 29) & 0x007U) // 3 bits + + // NOTE: variant is first parameter! This is to match vulkan/vulkan_core.h + #define VK_MAKE_API_VERSION(variant, major, minor, patch) (0\ + | (((uint32_t)(major & 0x07FU)) << 22) \ + | (((uint32_t)(minor & 0x3FFU)) << 12) \ + | (((uint32_t)(patch & 0xFFFU)) ) \ + | (((uint32_t)(variant & 0x007U)) << 29) ) + + #define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; + +// Types + VK_DEFINE_HANDLE(VkInstance); + + typedef enum VkResult + { + VK_SUCCESS = 0, + VK_RESULT_MAX_ENUM = 0x7FFFFFFF + } VkResult; + +// Prototypes + typedef void (VKAPI_PTR *PFN_vkVoidFunction )(void); + typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetInstanceProcAddr )(VkInstance instance, const char* pName); + typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceVersion)(uint32_t* pApiVersion); + namespace LLStatViewer { @@ -141,6 +188,7 @@ SimMeasurement<LLUnit<F64, LLUnits::Percent> > LLTrace::SampleStatHandle<> FPS_SAMPLE("fpssample"), NUM_IMAGES("numimagesstat"), NUM_RAW_IMAGES("numrawimagesstat"), + NUM_MATERIALS("nummaterials"), NUM_OBJECTS("numobjectsstat"), NUM_ACTIVE_OBJECTS("numactiveobjectsstat"), ENABLE_VBO("enablevbo", "Vertex Buffers Enabled"), @@ -157,10 +205,7 @@ LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > static LLTrace::SampleStatHandle<bool> CHAT_BUBBLES("chatbubbles", "Chat Bubbles Enabled"); -LLTrace::SampleStatHandle<F64Megabytes > GL_TEX_MEM("gltexmemstat"), - GL_BOUND_MEM("glboundmemstat"), - RAW_MEM("rawmemstat"), - FORMATTED_MEM("formattedmemstat"); +LLTrace::SampleStatHandle<F64Megabytes > FORMATTED_MEM("formattedmemstat"); LLTrace::SampleStatHandle<F64Kilobytes > DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"), MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting"); @@ -328,10 +373,10 @@ U32Bytes gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGOR extern U32 gVisCompared; extern U32 gVisTested; -LLFrameTimer gTextureTimer; - void update_statistics() { + LL_PROFILE_ZONE_SCOPED; + gTotalWorldData += gVLManager.getTotalBytes(); gTotalObjectData += gObjectData; @@ -363,16 +408,8 @@ void update_statistics() typedef LLTrace::StatType<LLTrace::TimeBlockAccumulator>::instance_tracker_t stat_type_t; - F64Seconds idle_secs = last_frame_recording.getSum(*stat_type_t::getInstance("Idle")); - F64Seconds network_secs = last_frame_recording.getSum(*stat_type_t::getInstance("Network")); - record(LLStatViewer::FRAME_STACKTIME, last_frame_recording.getSum(*stat_type_t::getInstance("Frame"))); - record(LLStatViewer::UPDATE_STACKTIME, idle_secs - network_secs); - record(LLStatViewer::NETWORK_STACKTIME, network_secs); - record(LLStatViewer::IMAGE_STACKTIME, last_frame_recording.getSum(*stat_type_t::getInstance("Update Images"))); - record(LLStatViewer::REBUILD_STACKTIME, last_frame_recording.getSum(*stat_type_t::getInstance("Sort Draw State"))); - record(LLStatViewer::RENDER_STACKTIME, last_frame_recording.getSum(*stat_type_t::getInstance("Render Geometry"))); - + if (gAgent.getRegion() && isAgentAvatarValid()) { LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost()); @@ -435,7 +472,7 @@ void update_statistics() auto tot_frame_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FRAME); // cumulative avatar time (includes idle processing, attachments and base av) - auto tot_avatar_time_raw = LLPerfStats::StatsRecorder::getSum(LLPerfStats::ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED); + auto tot_avatar_time_raw = LLPerfStats::us_to_raw(LLVOAvatar::getTotalGPURenderTime()); // cumulative avatar render specific time (a bit arbitrary as the processing is too.) // auto tot_av_idle_time_raw = LLPerfStats::StatsRecorder::getSum(AvType, LLPerfStats::StatType_t::RENDER_IDLE); // auto tot_avatar_render_time_raw = tot_avatar_time_raw - tot_av_idle_time_raw; @@ -508,19 +545,6 @@ void update_statistics() } } -void update_texture_time() -{ - if (gTextureList.isPrioRequestsFetched()) - { - gTextureTimer.pause(); - } - else - { - gTextureTimer.unpause(); - } - - record(LLStatViewer::TEXTURE_FETCH_TIME, gTextureTimer.getElapsedTimeF32()); -} /* * The sim-side LLSD is in newsim/llagentinfo.cpp:forwardViewerStats. * @@ -642,14 +666,11 @@ void send_viewer_stats(bool include_preferences) shader_level = 3; } } - else if (gPipeline.canUseWindLightShadersOnObjects()) + else { shader_level = 2; } - else if (gPipeline.shadersLoaded()) - { - shader_level = 1; - } + system["shader_level"] = shader_level; @@ -711,19 +732,76 @@ void send_viewer_stats(bool include_preferences) // detailed information on versions and extensions can come later. static bool vulkan_oneshot = false; static bool vulkan_detected = false; + static std::string vulkan_max_api_version( "0.0" ); // Unknown/None if (!vulkan_oneshot) { - HMODULE vulkan_loader = LoadLibraryExA("vulkan-1.dll", NULL, LOAD_LIBRARY_AS_DATAFILE); + // The 32-bit and 64-bit versions normally exist in: + // C:\Windows\System32 + // C:\Windows\SysWOW64 + HMODULE vulkan_loader = LoadLibraryA("vulkan-1.dll"); if (NULL != vulkan_loader) { vulkan_detected = true; + vulkan_max_api_version = "1.0"; // We have at least 1.0. See the note about vkEnumerateInstanceVersion() below. + + // We use Run-Time Dynamic Linking (via GetProcAddress()) instead of Load-Time Dynamic Linking (via directly calling vkGetInstanceProcAddr()). + // This allows us to: + // a) not need the header: #include <vulkan/vulkan.h> + // (and not need to set the corresponding "Additional Include Directories" as long as we provide the equivalent Vulkan types/prototypes/etc.) + // b) not need to link to: vulkan-1.lib + // (and not need to set the corresponding "Additional Library Directories") + // The former will allow Second Life to start and run even if the vulkan.dll is missing. + // The latter will require us to: + // a) link with vulkan-1.lib + // b) cause a System Error at startup if the .dll is not found: + // "The code execution cannot proceed because vulkan-1.dll was not found." + // + // See: + // https://docs.microsoft.com/en-us/windows/win32/dlls/using-run-time-dynamic-linking + // https://docs.microsoft.com/en-us/windows/win32/dlls/run-time-dynamic-linking + + // NOTE: Technically we can use GetProcAddress() as a replacement for vkGetInstanceProcAddr() + // but the canonical recommendation (mandate?) is to use vkGetInstanceProcAddr(). + PFN_vkGetInstanceProcAddr pGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) GetProcAddress(vulkan_loader, "vkGetInstanceProcAddr"); + if(pGetInstanceProcAddr) + { + // Check for vkEnumerateInstanceVersion. If it exists then we have at least 1.1 and can query the max API version. + // NOTE: Each VkPhysicalDevice that supports Vulkan has its own VkPhysicalDeviceProperties.apiVersion which is separate from the max API version! + // See: https://www.lunarg.com/wp-content/uploads/2019/02/Vulkan-1.1-Compatibility-Statement_01_19.pdf + PFN_vkEnumerateInstanceVersion pEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) pGetInstanceProcAddr(NULL, "vkEnumerateInstanceVersion"); + if(pEnumerateInstanceVersion) + { + uint32_t version = VK_MAKE_API_VERSION(0,1,1,0); // e.g. 4202631 = 1.2.135.0 + VkResult status = pEnumerateInstanceVersion( &version ); + if (status != VK_SUCCESS) + { + LL_INFOS("Vulkan") << "Failed to get Vulkan version. Assuming 1.0" << LL_ENDL; + } + else + { + // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#extendingvulkan-coreversions-versionnumbers + int major = VK_API_VERSION_MAJOR ( version ); + int minor = VK_API_VERSION_MINOR ( version ); + int patch = VK_API_VERSION_PATCH ( version ); + int variant = VK_API_VERSION_VARIANT( version ); + + vulkan_max_api_version = llformat( "%d.%d.%d.%d", major, minor, patch, variant ); + LL_INFOS("Vulkan") << "Vulkan API version: " << vulkan_max_api_version << ", Raw version: " << version << LL_ENDL; + } + } + } + else + { + LL_WARNS("Vulkan") << "FAILED to get Vulkan vkGetInstanceProcAddr()!" << LL_ENDL; + } FreeLibrary(vulkan_loader); } vulkan_oneshot = true; } misc["string_1"] = vulkan_detected ? llformat("Vulkan driver is detected") : llformat("No Vulkan driver detected"); + misc["VulkanMaxApiVersion"] = vulkan_max_api_version; #else misc["string_1"] = llformat("Unused"); @@ -751,12 +829,11 @@ void send_viewer_stats(bool include_preferences) LL_INFOS("LogViewerStatsPacket") << "Sending viewer statistics: " << body << LL_ENDL; - if (debugLoggingEnabled("LogViewerStatsPacket")) - { - std::string filename("viewer_stats_packet.xml"); - llofstream of(filename.c_str()); - LLSDSerialize::toPrettyXML(body,of); - } + LL_DEBUGS("LogViewerStatsPacket"); + std::string filename("viewer_stats_packet.xml"); + llofstream of(filename.c_str()); + LLSDSerialize::toPrettyXML(body,of); + LL_ENDL; // The session ID token must never appear in logs body["session_id"] = gAgentSessionID; |