X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=basic_stats.cpp;h=937e3021c5cdf1188a23c4b086d90e894bb75b01;hb=c094b73565559282001764edfbf0f4926d3197fb;hp=63d549309ca0f11a3cdd554cf86dc40ee0e22377;hpb=868450678563ed2c9fd5240dca704d87371d1478;p=nageru diff --git a/basic_stats.cpp b/basic_stats.cpp index 63d5493..937e302 100644 --- a/basic_stats.cpp +++ b/basic_stats.cpp @@ -3,13 +3,31 @@ #include #include +#include + +// Epoxy seems to be missing these. Taken from the NVX_gpu_memory_info spec. +#ifndef GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX +#define GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047 +#endif +#ifndef GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX +#define GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048 +#endif +#ifndef GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX +#define GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049 +#endif +#ifndef GPU_MEMORY_INFO_EVICTION_COUNT_NVX +#define GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A +#endif +#ifndef GPU_MEMORY_INFO_EVICTED_MEMORY_NVX +#define GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B +#endif using namespace std; using namespace std::chrono; bool uses_mlock = false; -BasicStats::BasicStats(bool verbose) +BasicStats::BasicStats(bool verbose, bool use_opengl) : verbose(verbose) { start = steady_clock::now(); @@ -20,6 +38,12 @@ BasicStats::BasicStats(bool verbose) global_metrics.add("start_time_seconds", &metric_start_time_seconds, Metrics::TYPE_GAUGE); global_metrics.add("memory_used_bytes", &metrics_memory_used_bytes); global_metrics.add("memory_locked_limit_bytes", &metrics_memory_locked_limit_bytes); + + // TODO: It would be nice to compile this out entirely for Kaeru, + // to avoid pulling in the symbols from libGL/Epoxy. + if (use_opengl) { + gpu_memory_stats.reset(new GPUMemoryStats(verbose)); + } } void BasicStats::update(int frame_num, int stats_dropped_frames) @@ -76,9 +100,57 @@ void BasicStats::update(int frame_num, int stats_dropped_frames) } } + if (gpu_memory_stats != nullptr) { + gpu_memory_stats->update(); + } + if (verbose) { printf("\n"); } } +GPUMemoryStats::GPUMemoryStats(bool verbose) + : verbose(verbose) +{ + // GL_NV_query_memory is exposed but supposedly only works on + // Quadro/Titan cards, so we use GL_NVX_gpu_memory_info even though it's + // formally marked as experimental. + // Intel/Mesa doesn't seem to have anything comparable (at least nothing + // that gets the amount of _available_ memory). + supported = epoxy_has_gl_extension("GL_NVX_gpu_memory_info"); + if (supported) { + global_metrics.add("memory_gpu_total_bytes", &metric_memory_gpu_total_bytes, Metrics::TYPE_GAUGE); + global_metrics.add("memory_gpu_dedicated_bytes", &metric_memory_gpu_dedicated_bytes, Metrics::TYPE_GAUGE); + global_metrics.add("memory_gpu_used_bytes", &metric_memory_gpu_used_bytes, Metrics::TYPE_GAUGE); + global_metrics.add("memory_gpu_evicted_bytes", &metric_memory_gpu_evicted_bytes, Metrics::TYPE_GAUGE); + global_metrics.add("memory_gpu_evictions", &metric_memory_gpu_evictions); + } +} +void GPUMemoryStats::update() +{ + if (!supported) { + return; + } + + GLint total, dedicated, available, evicted, evictions; + glGetIntegerv(GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &total); + glGetIntegerv(GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &dedicated); + glGetIntegerv(GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &available); + glGetIntegerv(GPU_MEMORY_INFO_EVICTED_MEMORY_NVX, &evicted); + glGetIntegerv(GPU_MEMORY_INFO_EVICTION_COUNT_NVX, &evictions); + + if (glGetError() == 0) { + metric_memory_gpu_total_bytes = int64_t(total) * 1024; + metric_memory_gpu_dedicated_bytes = int64_t(dedicated) * 1024; + metric_memory_gpu_used_bytes = int64_t(total - available) * 1024; + metric_memory_gpu_evicted_bytes = int64_t(evicted) * 1024; + metric_memory_gpu_evictions = evictions; + + if (verbose) { + printf(", using %d / %d MB GPU memory (%.1f%%)", + (total - available) / 1024, total / 1024, + float(100.0 * (total - available) / total)); + } + } +}