/* * Copyright (c) 2021-2023, Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ //! //! \file media_perf_profiler.h //! \brief Defines data structures and interfaces for media performance profiler. #ifndef __MEDIA_PERF_PROFILER_H__ #define __MEDIA_PERF_PROFILER_H__ #include #include #include #include #include "mos_defs.h" #include "mos_os.h" #include "media_class_trace.h" #include "mhw_mi_itf.h" #include "igfxfmid.h" #include "mos_defs_specific.h" #include "mos_os_specific.h" namespace mhw { namespace mi { class Itf; } } // namespace mhw using Map = std::map; /*! \brief In order to align GPU node value for all of OS, * we redifine the GPU node value here. */ typedef enum _PerfGPUNode { PERF_GPU_NODE_3D = 0, PERF_GPU_NODE_VIDEO = 1, PERF_GPU_NODE_BLT = 2, PERF_GPU_NODE_VE = 3, PERF_GPU_NODE_VIDEO2 = 4, PERF_GPU_NODE_TEE = 6, PERF_GPU_NODE_UNKNOW = 0xFF }PerfGPUNode; typedef enum _UMD_QUALITY_METRIC_ITEM { UMD_QUALITY_ITEM_SSEY = 0, UMD_QUALITY_ITEM_SSEU, UMD_QUALITY_ITEM_SSEV, UMD_QUALITY_ITEM_MEAN_SSIM_YU, UMD_QUALITY_ITEM_MEAN_SSIM_V } UMD_QUALITY_METRIC_ITEM; class MediaPerfProfiler { public: //! //! \brief Get the instance of the profiler //! //! \return pointer of profiler //! static MediaPerfProfiler *Instance(); //! //! \brief Destroy the resurces of profiler //! //! \param [in] profiler //! Pointer of profiler //! \param [in] context //! Pointer of Codechal/VPHal //! \param [in] osInterface //! Pointer of OS interface //! //! \return void //! static void Destroy(MediaPerfProfiler* profiler, void* context, MOS_INTERFACE *osInterface); //! //! \brief Initialize profiler and allcoate resources //! //! \param [in] context //! Pointer of Codechal/VPHal //! \param [in] osInterface //! Pointer of OS interface //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! virtual MOS_STATUS Initialize(void* context, MOS_INTERFACE *osInterface); //! //! \brief Insert start command of storing performance data //! //! \param [in] context //! Pointer of Codechal/VPHal //! \param [in] osInterface //! Pointer of OS interface //! \param [in] miItf //! Reference to Mhw MiItf. //! \param [in] cmdBuffer //! Pointer of OS command buffer //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! virtual MOS_STATUS AddPerfCollectStartCmd( void* context, MOS_INTERFACE *osInterface, std::shared_ptr miItf, MOS_COMMAND_BUFFER *cmdBuffer); //! //! \brief Insert end command of storing performance data //! //! \param [in] context //! Pointer of Codechal/VPHal //! \param [in] osInterface //! Pointer of OS interface //! \param [in] miItf //! Reference to Mhw MiItf. //! \param [in] cmdBuffer //! Pointer of OS command buffer //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! virtual MOS_STATUS AddPerfCollectEndCmd( void* context, MOS_INTERFACE *osInterface, std::shared_ptr miItf, MOS_COMMAND_BUFFER *cmdBuffer); //! //! \brief Deconstructor //! virtual ~MediaPerfProfiler(); private: //! //! \brief Constructor //! MediaPerfProfiler(); //! //! \brief Save data to the buffer which store the performance data //! //! \param [in] miItf //! Reference to Mhw MiItf. //! \param [in] cmdBuffer //! Pointer of OS command buffer //! \param [in] pOsContext //! Pointer of DEVICE CONTEXT //! \param [in] offset //! Offset in the buffer //! \param [in] value //! Value of data //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! MOS_STATUS StoreData( std::shared_ptr miItf, PMOS_COMMAND_BUFFER cmdBuffer, MOS_CONTEXT_HANDLE pOsContext, uint32_t offset, uint32_t value); //! //! \brief Save register value to the buffer which store the performance data //! \param [in] osInterface //! Pointer of MOS_INTERFACE //! //! \param [in] miItf //! Reference to Mhw MiItf. //! \param [in] cmdBuffer //! Pointer of OS command buffer //! \param [in] offset //! Offset in the buffer //! \param [in] reg //! Address of register //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! MOS_STATUS StoreRegister( MOS_INTERFACE *osInterface, std::shared_ptr miItf, PMOS_COMMAND_BUFFER cmdBuffer, uint32_t offset, uint32_t reg); //! //! \brief Save timestamp to the buffer by Pipe control command //! //! \param [in] miItf //! Reference to Mhw MiItf. //! \param [in] cmdBuffer //! Pointer of OS command buffer //! \param [in] pOsContext //! Pointer of DEVICE CONTEXT //! \param [in] offset //! Offset in the buffer //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! MOS_STATUS StoreTSByPipeCtrl( std::shared_ptr miItf, PMOS_COMMAND_BUFFER cmdBuffer, MOS_CONTEXT_HANDLE pOsContext, uint32_t offset); //! //! \brief Save timestamp to the buffer by MI command //! //! \param [in] miItf //! Reference to Mhw MiItf. //! \param [in] pOsContext //! Pointer of DEVICE CONTEXT //! \param [in] cmdBuffer //! Pointer of OS command buffer //! \param [in] offset //! Offset in the buffer //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! MOS_STATUS StoreTSByMiFlush( std::shared_ptr miItf, PMOS_COMMAND_BUFFER cmdBuffer, MOS_CONTEXT_HANDLE pOsContext, uint32_t offset); //! //! \brief Save performance data in to a file //! //! \param [in] osInterface //! Pointer of OS interface //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! MOS_STATUS SavePerfData(MOS_INTERFACE *osInterface); //! //! \brief Convert GPU context to GPU node //! //! \param [in] context //! GPU context //! //! \return PerfGPUNode //! PerfGPUNode GpuContextToGpuNode(MOS_GPU_CONTEXT context); //! //! \brief Check the performance mode //! //! \param [in] regs //! The registers' array //! //! \return bool //! true if include the memory information //! bool IsPerfModeWidthMemInfo(uint32_t *regs); //! //! \brief Map the platform ID //! //! \param [in] platform //! //! \return uint32_t //! mapped platform id used to fill node header //! uint32_t PlatFormIdMap(PLATFORM platform); //! //! \brief Save data to the buffer which store the performance data //! //! \param [in] miInterface //! Pointer of MI interface //! \param [in] cmdBuffer //! Pointer of OS command buffer //! \param [in] pOsContext //! Pointer of DEVICE CONTEXT //! \param [in] offset //! Offset in the buffer //! \param [in] value //! Value of data //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! MOS_STATUS StoreData( MhwMiInterface *miInterface, PMOS_COMMAND_BUFFER cmdBuffer, PMOS_CONTEXT pOsContext, uint32_t offset, uint32_t value); //! //! \brief Save data to the buffer which store the performance data //! //! \param [in] miInterface //! Pointer of MI interface //! \param [in] cmdBuffer //! Pointer of OS command buffer //! \param [in] pOsContext //! Pointer of DEVICE CONTEXT //! \param [in] offset //! Offset in the buffer //! \param [in] value //! Value of data //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! MOS_STATUS StoreDataNext( MhwMiInterface *miInterface, PMOS_COMMAND_BUFFER cmdBuffer, PMOS_CONTEXT pOsContext, uint32_t offset, uint32_t value); //! //! \brief Save register value to the buffer which store the performance data //! \param [in] osInterface //! Pointer of MOS_INTERFACE //! //! \param [in] miInterface //! Pointer of MI interface //! \param [in] cmdBuffer //! Pointer of OS command buffer //! \param [in] offset //! Offset in the buffer //! \param [in] reg //! Address of register //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! MOS_STATUS StoreRegister( MOS_INTERFACE *osInterface, MhwMiInterface *miInterface, PMOS_COMMAND_BUFFER cmdBuffer, uint32_t offset, uint32_t reg); //! //! \brief Save register value to the buffer which store the performance data //! \param [in] osInterface //! Pointer of MOS_INTERFACE //! //! \param [in] miInterface //! Pointer of MI interface //! \param [in] cmdBuffer //! Pointer of OS command buffer //! \param [in] offset //! Offset in the buffer //! \param [in] reg //! Address of register //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! MOS_STATUS StoreRegisterNext( MOS_INTERFACE *osInterface, MhwMiInterface *miInterface, PMOS_COMMAND_BUFFER cmdBuffer, uint32_t offset, uint32_t reg); //! //! \brief Save timestamp to the buffer by Pipe control command //! //! \param [in] miInterface //! Pointer of MI interface //! \param [in] cmdBuffer //! Pointer of OS command buffer //! \param [in] pOsContext //! Pointer of DEVICE CONTEXT //! \param [in] offset //! Offset in the buffer //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! MOS_STATUS StoreTSByPipeCtrl( MhwMiInterface *miInterface, PMOS_COMMAND_BUFFER cmdBuffer, PMOS_CONTEXT pOsContext, uint32_t offset); //! //! \brief Save timestamp to the buffer by Pipe control command //! //! \param [in] miInterface //! Pointer of MI interface //! \param [in] cmdBuffer //! Pointer of OS command buffer //! \param [in] pOsContext //! Pointer of DEVICE CONTEXT //! \param [in] offset //! Offset in the buffer //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! MOS_STATUS StoreTSByPipeCtrlNext( MhwMiInterface *miInterface, PMOS_COMMAND_BUFFER cmdBuffer, PMOS_CONTEXT pOsContext, uint32_t offset); //! //! \brief Save timestamp to the buffer by MI command //! //! \param [in] miInterface //! Pointer of MI interface //! \param [in] cmdBuffer //! Pointer of OS command buffer //! \param [in] pOsContext //! Pointer of DEVICE CONTEXT //! \param [in] offset //! Offset in the buffer //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! MOS_STATUS StoreTSByMiFlush( MhwMiInterface *miInterface, PMOS_COMMAND_BUFFER cmdBuffer, PMOS_CONTEXT pOsContext, uint32_t offset); //! //! \brief Save timestamp to the buffer by MI command //! //! \param [in] miInterface //! Pointer of MI interface //! \param [in] cmdBuffer //! Pointer of OS command buffer //! \param [in] pOsContext //! Pointer of DEVICE CONTEXT //! \param [in] offset //! Offset in the buffer //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! MOS_STATUS StoreTSByMiFlushNext( MhwMiInterface* miInterface, PMOS_COMMAND_BUFFER cmdBuffer, PMOS_CONTEXT pOsContext, uint32_t offset); //! //! \brief Copy DW data from src to dst //! //! \param [in] miInterface //! Pointer of MI interface //! \param [in] cmdBuffer //! Pointer of OS command buffer //! \param [in] pOsContext //! Pointer of DEVICE CONTEXT //! \param [in] presSrc //! SRC resource //! \param [in] dwSrcOffset //! Offset in the SRC //! \param [in] dwDstOffset //! Offset in the DS //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! MOS_STATUS CopyMemData( std::shared_ptr& miItf, PMOS_COMMAND_BUFFER cmdBuffer, MOS_CONTEXT_HANDLE pOsContext, PMOS_RESOURCE presSrc, uint32_t dwSrcOffset, uint32_t dwDstOffset); public: //! //! \brief Insert start command of storing performance data //! //! \param [in] context //! Pointer of Codechal/VPHal //! \param [in] osInterface //! Pointer of OS interface //! \param [in] miInterface //! pointer of MI interface //! \param [in] cmdBuffer //! Pointer of OS command buffer //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! virtual MOS_STATUS AddPerfCollectStartCmd( void* context, MOS_INTERFACE *osInterface, MhwMiInterface *miInterface, MOS_COMMAND_BUFFER *cmdBuffer); //! //! \brief Insert end command of storing performance data //! //! \param [in] context //! Pointer of Codechal/VPHal //! \param [in] osInterface //! Pointer of OS interface //! \param [in] miInterface //! pointer of MI interface //! \param [in] cmdBuffer //! Pointer of OS command buffer //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! virtual MOS_STATUS AddPerfCollectEndCmd( void* context, MOS_INTERFACE *osInterface, MhwMiInterface *miInterface, MOS_COMMAND_BUFFER *cmdBuffer); //! //! \brief Insert MEM Copy command of storing quality data //! //! \param [in] context //! Pointer of Codechal/VPHal //! \param [in] osInterface //! Pointer of OS interface //! \param [in] miInterface //! pointer of MI interface //! \param [in] cmdBuffer //! Pointer of OS command buffer //! \param [in] item //! Quality metric item //! \param [in] presSrc //! SRC resource //! \param [in] dwSrcOffset //! Offset in the SRC //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! MOS_STATUS AddCopyQualityMetricCmd( void *context, MOS_INTERFACE *osInterface, std::shared_ptr& miItf, MOS_COMMAND_BUFFER *cmdBuffer, UMD_QUALITY_METRIC_ITEM item, PMOS_RESOURCE presSrc, uint32_t dwSrcOffset); //! //! \brief Insert MEM Copy command of storing quality data //! //! \param [in] context //! Pointer of Codechal/VPHal //! \param [in] osInterface //! Pointer of OS interface //! \param [in] miInterface //! pointer of MI interface //! \param [in] cmdBuffer //! Pointer of OS command buffer //! \param [in] reg //! Address of register //! //! \return MOS_STATUS //! MOS_STATUS_SUCCESS if success, else fail reason //! MOS_STATUS AddStoreBitstreamSizeCmd( void *context, MOS_INTERFACE *osInterface, std::shared_ptr& miItf, MOS_COMMAND_BUFFER *cmdBuffer, uint32_t reg); private: std::unordered_map m_perfStoreBufferMap; //!< Buffer for perf data collection std::unordered_map m_refMap; //!< The number of refereces std::unordered_map m_perfDataIndexMap; //!< The index of performance data node in buffer std::unordered_map m_initializedMap; //!< Indicate whether profiler was initialized Map m_contextIndexMap; //!< Map between CodecHal/VPHal and PerfDataContext PMOS_MUTEX m_mutex = nullptr; //!< Mutex for protecting data of profiler when refereced multi times uint32_t m_bufferSize = 10000000; //!< The size of perf data buffer uint32_t m_timerBase = 0; //!< time frequency int32_t m_multiprocess = 0; //!< multi process support uint32_t m_registers[8] = { 0 }; //!< registers of Memory information const std::string m_registersKey[8] = {__MEDIA_USER_FEATURE_VALUE_PERF_PROFILER_REGISTER_KEY_1, __MEDIA_USER_FEATURE_VALUE_PERF_PROFILER_REGISTER_KEY_2, __MEDIA_USER_FEATURE_VALUE_PERF_PROFILER_REGISTER_KEY_3, __MEDIA_USER_FEATURE_VALUE_PERF_PROFILER_REGISTER_KEY_4, __MEDIA_USER_FEATURE_VALUE_PERF_PROFILER_REGISTER_KEY_5, __MEDIA_USER_FEATURE_VALUE_PERF_PROFILER_REGISTER_KEY_6, __MEDIA_USER_FEATURE_VALUE_PERF_PROFILER_REGISTER_KEY_7, __MEDIA_USER_FEATURE_VALUE_PERF_PROFILER_REGISTER_KEY_8}; //!< registers key int32_t m_profilerEnabled; //!< UMD Perf Profiler enable or not std::string m_outputFileName = ""; //!< Name of output file bool m_enableProfilerDump = true; //!< Indicate whether enable UMD Profiler dump std::shared_ptr m_miItf = nullptr; int32_t m_multiprocesssinglebin = 0; //!< multi process single binary flag int32_t m_mergeheader = 0; //!< multi header support uint32_t* m_perfDataCombined = nullptr; //!< Combined perf data pointer uint32_t m_perfDataCombinedSize = 0; //!< Combined perf data size uint32_t m_perfDataCombinedIndex = 0; //!< Combined perf data index uint32_t m_perfDataCombinedOffset = 0; //!< Combined perf data offset MEDIA_CLASS_DEFINE_END(MediaPerfProfiler) }; #endif // __MEDIA_PERF_PROFILER_H__