Statistics HUD: smooth CPU/GPU usage, add GPU Memory for mode 3; CMakeLists: make VMA header visible in IDE

(cherry picked from commit 8a0c493f1c4ef45312005c7e5b02cdde706bcc2b)
This commit is contained in:
Stephen Saunders 2023-11-30 12:26:38 -05:00
parent 48381ec0b9
commit ec2719b099
5 changed files with 66 additions and 11 deletions

View file

@ -429,6 +429,8 @@ if(USE_VULKAN)
if(USE_VMA)
add_definitions(-DUSE_AMD_ALLOCATOR)
include_directories("libs/vma/include")
file(GLOB VMA_INCLUDES libs/vma/include/*.h)
source_group("libs\\vma" FILES ${VMA_INCLUDES})
endif()
endif()
@ -1304,6 +1306,7 @@ set(RBDOOM3_INCLUDES
#${FREETYPE_SOURCES}
${SOUND_INCLUDES}
${OGGVORBIS_INCLUDES}
${VMA_INCLUDES}
${OPTICK_INCLUDES}
${UI_INCLUDES}
${SWF_INCLUDES}

View file

@ -382,13 +382,24 @@ public:
// SRS start
void SetRendererMvkEncodeMicroseconds( uint64 mvkEncodeMicroSeconds )
{
mvkEncodeMicroSec = mvkEncodeMicroSeconds;
metal_encode = mvkEncodeMicroSeconds;
return;
}
uint64 GetRendererMvkEncodeMicroseconds() const
{
return mvkEncodeMicroSec;
return metal_encode;
}
void SetRendererGpuMemoryMB( int gpuMemoryMB )
{
gpu_memory = gpuMemoryMB;
return;
}
int GetRendererGpuMemoryMB() const
{
return gpu_memory;
}
// SRS end
@ -604,8 +615,11 @@ private:
// RB: r_speeds counters
backEndCounters_t stats_backend;
performanceCounters_t stats_frontend;
// SRS - MoltenVK's Vulkan to Metal command buffer encoding time, set default to 0 for non-macOS platforms (Windows and Linux)
uint64 mvkEncodeMicroSec = 0;
uint64 metal_encode = 0;
// SRS - Cross-platform GPU Memory usage counter, set default to 0 in case platform or graphics API does not support queries
int gpu_memory = 0;
// Used during loading screens
int lastPacifierSessionTime;

View file

@ -225,8 +225,10 @@ float idConsoleLocal::DrawFPS( float y )
extern idCVar r_swapInterval;
static float previousTimes[FPS_FRAMES];
static float previousCpuUsage[FPS_FRAMES] = {};
static float previousGpuUsage[FPS_FRAMES] = {};
static float previousTimesNormalized[FPS_FRAMES_HISTORY];
static int index;
static int index = 0;
static int previous;
static int valuesOffset = 0;
@ -239,6 +241,8 @@ float idConsoleLocal::DrawFPS( float y )
previous = t;
int fps = 0;
float cpuUsage = 0.0;
float gpuUsage = 0.0;
const float milliSecondsPerFrame = 1000.0f / com_engineHz_latched;
@ -253,6 +257,8 @@ float idConsoleLocal::DrawFPS( float y )
for( int i = 0 ; i < FPS_FRAMES ; i++ )
{
total += previousTimes[i];
cpuUsage += previousCpuUsage[i];
gpuUsage += previousGpuUsage[i];
}
if( !total )
{
@ -260,6 +266,8 @@ float idConsoleLocal::DrawFPS( float y )
}
fps = 1000000 * FPS_FRAMES / total;
fps = ( fps + 500 ) / 1000;
cpuUsage /= FPS_FRAMES;
gpuUsage /= FPS_FRAMES;
const char* s = va( "%ifps", fps );
int w = strlen( s ) * BIGCHAR_WIDTH;
@ -316,6 +324,10 @@ float idConsoleLocal::DrawFPS( float y )
// SRS - GPU idle time is simply the difference between measured frame-over-frame time and GPU busy time (directly from GPU timers)
const int64 rendererGPUIdleTime = frameBusyTime + frameIdleTime - rendererGPUTime;
// SRS - Save current CPU and GPU usage factors in ring buffer to calculate smoothed averages for future frames
previousCpuUsage[(index - 1) % FPS_FRAMES] = float( frameBusyTime - frameSyncTime ) / float( frameBusyTime + frameIdleTime ) * 100.0;
previousGpuUsage[(index - 1) % FPS_FRAMES] = float( rendererGPUTime ) / float( rendererGPUTime + rendererGPUIdleTime ) * 100.0;
#if 1
// RB: use ImGui to show more detailed stats about the scene loads
@ -428,7 +440,7 @@ float idConsoleLocal::DrawFPS( float y )
ImGui::TextColored( colorCyan, "API: %s, AA[%i, %i]: %s, %s", API, width, height, aaMode, resolutionText.c_str() );
ImGui::TextColored( colorGold, "Device: %s", deviceManager->GetRendererString() );
ImGui::TextColored( colorGold, "Device: %s, Memory: %i MB", deviceManager->GetRendererString(), commonLocal.GetRendererGpuMemoryMB() );
ImGui::TextColored( colorLtGrey, "GENERAL: views:%i draws:%i tris:%i",
commonLocal.stats_frontend.c_numViews,
@ -478,7 +490,7 @@ float idConsoleLocal::DrawFPS( float y )
if( com_showFPS.GetInteger() > 2 )
{
const char* overlay = va( "Average FPS %i", fps );
const char* overlay = va( "Average FPS %-4i", fps );
ImGui::PlotLines( "Relative\nFrametime ms", previousTimesNormalized, FPS_FRAMES_HISTORY, valuesOffset, overlay, -10.0f, 10.0f, ImVec2( 0, 50 ) );
}
@ -508,7 +520,7 @@ float idConsoleLocal::DrawFPS( float y )
ImGui::TextColored( frameBusyTime > maxTime || rendererGPUTime > maxTime ? colorRed : colorWhite, "Total: %5lld us Total: %5lld us", frameBusyTime, rendererGPUTime );
ImGui::TextColored( colorWhite, "Idle: %5lld us Idle: %5lld us", frameIdleTime, rendererGPUIdleTime );
// SRS - Show CPU and GPU overall usage statistics
ImGui::TextColored( colorWhite, "Usage: %3.0f %% Usage: %3.0f %%", float( frameBusyTime - frameSyncTime ) / float( frameBusyTime + frameIdleTime ) * 100.0, float( rendererGPUTime ) / float( rendererGPUTime + rendererGPUIdleTime ) * 100.0 );
ImGui::TextColored( colorWhite, "Usage: %3.0f %% Usage: %3.0f %%", cpuUsage, gpuUsage );
ImGui::End();
}

View file

@ -27,6 +27,7 @@
#include "renderer/RenderCommon.h"
#include "renderer/RenderSystem.h"
#include "framework/Common_local.h"
#include <sys/DeviceManager.h>
#include <Windows.h>
@ -57,7 +58,7 @@ class DeviceManager_DX12 : public DeviceManager
RefCountPtr<IDXGISwapChain3> m_SwapChain;
DXGI_SWAP_CHAIN_DESC1 m_SwapChainDesc{};
DXGI_SWAP_CHAIN_FULLSCREEN_DESC m_FullScreenDesc{};
RefCountPtr<IDXGIAdapter> m_DxgiAdapter;
RefCountPtr<IDXGIAdapter3> m_DxgiAdapter;
bool m_TearingSupported = false;
std::vector<RefCountPtr<ID3D12Resource>> m_SwapChainBuffers;
@ -388,7 +389,7 @@ bool DeviceManager_DX12::CreateDeviceAndSwapChain()
}
}
m_DxgiAdapter = targetAdapter;
targetAdapter->QueryInterface( IID_PPV_ARGS( &m_DxgiAdapter ) );
D3D12_COMMAND_QUEUE_DESC queueDesc;
ZeroMemory( &queueDesc, sizeof( queueDesc ) );
@ -566,6 +567,12 @@ void DeviceManager_DX12::ResizeSwapChain()
void DeviceManager_DX12::BeginFrame()
{
OPTICK_CATEGORY( "DX12_BeginFrame", Optick::Category::Wait );
// SRS - get DXGI GPU memory usage for display in statistics overlay HUD
DXGI_QUERY_VIDEO_MEMORY_INFO memoryInfoLocal = {}, memoryInfoNonLocal = {};
m_DxgiAdapter->QueryVideoMemoryInfo( 0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &memoryInfoLocal );
m_DxgiAdapter->QueryVideoMemoryInfo( 0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &memoryInfoNonLocal );
commonLocal.SetRendererGpuMemoryMB( int( ( memoryInfoLocal.CurrentUsage + memoryInfoNonLocal.CurrentUsage ) / 1024 / 1024 ) );
}
nvrhi::ITexture* DeviceManager_DX12::GetCurrentBackBuffer()

View file

@ -32,13 +32,13 @@
#include <unordered_set>
#include "renderer/RenderCommon.h"
#include "framework/Common_local.h"
#include <sys/DeviceManager.h>
#include <nvrhi/vulkan.h>
// SRS - optionally needed for MoltenVK runtime config visibility
#if defined(__APPLE__) && defined( USE_MoltenVK )
#include <MoltenVK/vk_mvk_moltenvk.h>
#include "framework/Common_local.h"
idCVar r_mvkSynchronousQueueSubmits( "r_mvkSynchronousQueueSubmits", "0", CVAR_BOOL | CVAR_INIT, "Use MoltenVK's synchronous queue submit option." );
#endif
#include <nvrhi/validation.h>
@ -222,6 +222,9 @@ private:
#endif
#if defined( VK_KHR_format_feature_flags2 )
VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME,
#endif
#if defined( VK_EXT_memory_budget )
VK_EXT_MEMORY_BUDGET_EXTENSION_NAME,
#endif
VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME
},
@ -1335,14 +1338,30 @@ void DeviceManager_VK::DestroyDeviceAndSwapChain()
void DeviceManager_VK::BeginFrame()
{
OPTICK_CATEGORY( "Vulkan_BeginFrame", Optick::Category::Wait );
#if defined(__APPLE__) && defined( USE_MoltenVK )
#if MVK_VERSION >= MVK_MAKE_VERSION( 1, 2, 6 )
// SRS - fetch MoltenVK's Vulkan to Metal encoding time for the previous frame
// SRS - get MoltenVK's Metal encoding time and GPU memory usage for display in statistics overlay HUD
MVKPerformanceStatistics mvkPerfStats;
size_t mvkPerfStatsSize = sizeof( mvkPerfStats );
vkGetPerformanceStatisticsMVK( m_VulkanDevice, &mvkPerfStats, &mvkPerfStatsSize );
commonLocal.SetRendererMvkEncodeMicroseconds( uint64( Max( 0.0, mvkPerfStats.queue.submitCommandBuffers.latest - mvkPerfStats.queue.retrieveCAMetalDrawable.latest ) * 1000.0 ) );
commonLocal.SetRendererGpuMemoryMB( int( mvkPerfStats.device.gpuMemoryAllocated.latest / 1024.0 ) );
#endif
#elif defined( VK_EXT_memory_budget )
// SRS - get Vulkan GPU memory usage for display in statistics overlay HUD
vk::PhysicalDeviceMemoryProperties2 memoryProperties2;
vk::PhysicalDeviceMemoryBudgetPropertiesEXT memoryBudget;
memoryProperties2.pNext = &memoryBudget;
m_VulkanPhysicalDevice.getMemoryProperties2( &memoryProperties2 );
VkDeviceSize gpuMemoryAllocated = 0;
for( uint32_t i = 0; i < memoryProperties2.memoryProperties.memoryHeapCount; i++ )
{
gpuMemoryAllocated += memoryBudget.heapUsage[i];
}
commonLocal.SetRendererGpuMemoryMB( int( gpuMemoryAllocated / 1024 / 1024 ) );
#endif
const vk::Result res = m_VulkanDevice.acquireNextImageKHR( m_SwapChain,