diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index 5d1191af4f..9fba6cc6c1 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -782,6 +782,7 @@ LinkedShader *ShaderManagerGLES::ApplyFragmentShader(VShaderID VSID, Shader *vs, // Check if we can link these. ls = new LinkedShader(render_, VSID, vs, FSID, fs, vs->UseHWTransform()); + gpuStats.totals.numPipelinesCreated++; ls->use(VSID); const LinkedShaderCacheEntry entry(vs, fs, ls); linkedShaderCache_.push_back(entry); @@ -1032,6 +1033,7 @@ bool ShaderManagerGLES::LoadCache(File::IOFile &f) { fsCache_.Get(fsid, &fs); if (vs && fs) { LinkedShader *ls = new LinkedShader(render_, vsid, vs, fsid, fs, vs->UseHWTransform(), true); + gpuStats.totals.numPipelinesCreated++; LinkedShaderCacheEntry entry(vs, fs, ls); linkedShaderCache_.push_back(entry); } diff --git a/GPU/GPU.h b/GPU/GPU.h index 2f8307d702..1ad02603a0 100644 --- a/GPU/GPU.h +++ b/GPU/GPU.h @@ -148,6 +148,8 @@ struct GPUStatsPerFrame { struct GPUStatsTotals { // Flip count. Doesn't really belong here. int numFlips; + // Vulkan and Metal pipelines, and OpenGL programs, including those precompiled from the shader cache. + int numPipelinesCreated; }; // The ToString function lives in GPUCommonHW.cpp. diff --git a/GPU/Metal/DrawEngineMetal.mm b/GPU/Metal/DrawEngineMetal.mm index b93a0eb1a8..9098dd60e4 100644 --- a/GPU/Metal/DrawEngineMetal.mm +++ b/GPU/Metal/DrawEngineMetal.mm @@ -278,6 +278,7 @@ DrawEngineMetal::Pipeline *DrawEngineMetal::GetOrCreatePipeline(const MetalPipel pipeline->state = [MetalPipelineState new]; pipeline->format = format; pipelines_.Insert(key, pipeline); + gpuStats.totals.numPipelinesCreated++; if (vs->Failed() || fs->Failed()) { [pipeline->state setPipeline:nil]; return pipeline; diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index 9478b3c4e8..575ba1c33e 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -11,6 +11,7 @@ #include "GPU/Vulkan/ShaderManagerVulkan.h" #include "GPU/Common/ShaderId.h" #include "GPU/GPUDefinitions.h" +#include "GPU/GPU.h" #include "Common/GPU/thin3d.h" #include "Common/GPU/Vulkan/VulkanRenderManager.h" #include "Common/GPU/Vulkan/VulkanQueueRunner.h" @@ -396,6 +397,7 @@ VulkanPipeline *PipelineManagerVulkan::GetOrCreatePipeline(VulkanRenderManager * // If the above failed, we got a null pipeline. We still insert it to keep track. pipelines_.Insert(key, pipeline); + gpuStats.totals.numPipelinesCreated++; // Don't return placeholder null pipelines. if (pipeline && pipeline->pipeline) { diff --git a/headless/Headless.cpp b/headless/Headless.cpp index a4a1b86c8d..0d4db7238e 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -766,6 +766,8 @@ static bool RunAutoTest(GraphicsContext *graphicsContext, CoreParameter &corePar } fprintf(stderr, "Frame stats: %d flips in %d emulated seconds, wall %.1fs, per second:%s\n", total, (int)flipsPerSecond.size(), time_now_d() - startTime, perSecond.c_str()); } + // What shader compiles cost the run, which the times include. + fprintf(stderr, "Pipelines created: %d\n", gpuStats.totals.numPipelinesCreated); if (coreParameter.bootFromState) { // Counted from the state's load. More than a few, and the game has gone off its usual path. fprintf(stderr, "Failed disc reads: %d\n", pspFileSystem.FailedDiscReads());