diff --git a/src/Cafe/CMakeLists.txt b/src/Cafe/CMakeLists.txt index 100f00d8..634014b7 100644 --- a/src/Cafe/CMakeLists.txt +++ b/src/Cafe/CMakeLists.txt @@ -567,6 +567,7 @@ if(ENABLE_METAL) HW/Latte/Renderer/Metal/MetalSamplerCache.h HW/Latte/Renderer/Metal/MetalHybridComputePipeline.cpp HW/Latte/Renderer/Metal/MetalHybridComputePipeline.h + HW/Latte/Renderer/Metal/MetalPerformanceMonitor.h HW/Latte/Renderer/Metal/UtilityShaderSource.h ) diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalBufferAllocator.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalBufferAllocator.h index 9853ae7f..3ec0acbd 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalBufferAllocator.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalBufferAllocator.h @@ -93,6 +93,9 @@ public: m_freeBufferRanges.push_back(range); } + // Debug + m_mtlr->GetPerformanceMonitor().m_bufferAllocatorMemory += m_allocationSize; + // Increase the allocation size for the next buffer if (m_allocationSize < 128 * 1024 * 1024) m_allocationSize *= 2; diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalPerformanceMonitor.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalPerformanceMonitor.h new file mode 100644 index 00000000..64e94d38 --- /dev/null +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalPerformanceMonitor.h @@ -0,0 +1,18 @@ +#pragma once + +class MetalPerformanceMonitor +{ +public: + size_t m_bufferAllocatorMemory = 0; + + // Per frame data + uint32 m_renderPasses = 0; + + MetalPerformanceMonitor() = default; + ~MetalPerformanceMonitor() = default; + + void ResetPerFrameData() + { + m_renderPasses = 0; + } +}; diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.h index 30f40208..ec4cabbf 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.h @@ -20,6 +20,9 @@ public: MTL::RenderPipelineState* GetMeshPipelineState(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* geometryShader, const LatteDecompilerShader* pixelShader, class CachedFBOMtl* activeFBO, const LatteContextRegister& lcr, Renderer::INDEX_TYPE hostIndexType); + // Debug + size_t GetPipelineCacheSize() const { return m_pipelineCache.size(); } + private: class MetalRenderer* m_mtlr; diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp index bc5b83ac..dfbbb2cc 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp @@ -395,7 +395,13 @@ void MetalRenderer::DeleteFontTextures() void MetalRenderer::AppendOverlayDebugInfo() { - // TODO: implement + ImGui::Text("--- Metal info ---"); + ImGui::Text("Render pipeline states %zu", m_pipelineCache->GetPipelineCacheSize()); + ImGui::Text("Buffer allocator memory %zuMB", m_performanceMonitor.m_bufferAllocatorMemory / 1024 / 1024); + + ImGui::Text("--- Metal info (per frame) ---"); + ImGui::Text("Command buffers %zu", m_commandBuffers.size()); + ImGui::Text("Render passes %u", m_performanceMonitor.m_renderPasses); } // TODO: halfZ @@ -1725,6 +1731,9 @@ void MetalRenderer::SwapBuffer(bool mainWindow) { debug_printf("skipped present!\n"); } + + // Debug + m_performanceMonitor.ResetPerFrameData(); } void MetalRenderer::EnsureImGuiBackend() diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h index 5b34d630..d1f0eaeb 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h @@ -3,6 +3,7 @@ #include "Cafe/HW/Latte/Renderer/Renderer.h" #include "Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.h" +#include "Cafe/HW/Latte/Renderer/Metal/MetalPerformanceMonitor.h" struct MetalBufferAllocation { @@ -312,6 +313,8 @@ public: } // Helpers + MetalPerformanceMonitor& GetPerformanceMonitor() { return m_performanceMonitor; } + MTL::CommandBuffer* GetCurrentCommandBuffer() { cemu_assert_debug(m_commandBuffers.size() != 0); @@ -407,6 +410,8 @@ private: MetalLayerHandle m_mainLayer; MetalLayerHandle m_padLayer; + MetalPerformanceMonitor m_performanceMonitor; + // Metal objects MTL::Device* m_device; MTL::CommandQueue* m_commandQueue;