/*---------------------------------------------------------------------------* Copyright (C) 2010-2011 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. *---------------------------------------------------------------------------*/ // gx2Perf.h // // Declares GPU performance APIs for gx2 library. #ifndef _CAFE_GX2_PERF2_H_ #define _CAFE_GX2_PERF2_H_ #ifdef __cplusplus extern "C" { #endif #include #define GX2_PERF_DATA_RESERVED_SIZE 0x8a0 /// @addtogroup GX2PerfHighStructGroup /// @{ /// \brief Function to convert tag id to string /// typedef u32 GX2PerfTag; typedef const char* (*GX2PerfTag2StringFunc)(GX2PerfTag tag); /// \brief Metric result used to return values from result query calls /// typedef union _GX2MetricResult { f32 f32Result; /// < f32 result u64 u64Result; /// < u64 resuls } GX2MetricResult; /// \brief Perf data collection. /// typedef struct _GX2PerfData { u8 reserved[GX2_PERF_DATA_RESERVED_SIZE]; } GX2PerfData; #define GX2_INVALID_METRIC_NAME "invalid_metric_specified" /// \brief Indicates the perf metric type. /// typedef enum _GX2PerfMetricType { GX2_PERF_METRICTYPE_U64, GX2_PERF_METRICTYPE_F32 } GX2PerfMetricType; /// @} /// @addtogroup GX2PerfHighResultsGroup /// @{ /// \brief This function returns a string with the name of a specified GX2 perf metric. /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE const char* GX2GetPerfMetricName(GX2PerfMetric metric) { ASSERT(metric <= GX2_PERF_LAST); switch(metric) { case GX2_PERF_U64_TIME: return "GX2_PERF_U64_TIME"; // 0 case GX2_PERF_U64_GPU_TIME: return "GX2_PERF_U64_GPU_TIME"; // 1 case GX2_PERF_F32_GPU_BUSY: return "GX2_PERF_F32_GPU_BUSY"; // 2 case GX2_PERF_F32_SHADER_BUSY: return "GX2_PERF_F32_SHADER_BUSY"; // 3 case GX2_PERF_U64_REUSED_INDICES_VS: return "GX2_PERF_U64_REUSED_INDICES_VS"; // 4 case GX2_PERF_F32_SHADER_BUSY_VS: return "GX2_PERF_F32_SHADER_BUSY_VS"; // 5 case GX2_PERF_F32_SHADER_BUSY_GS: return "GX2_PERF_F32_SHADER_BUSY_GS"; // 6 case GX2_PERF_F32_SHADER_BUSY_PS: return "GX2_PERF_F32_SHADER_BUSY_PS"; // 7 case GX2_PERF_F32_ALU_BUSY: return "GX2_PERF_F32_ALU_BUSY"; // 8 case GX2_PERF_F32_TEX_BUSY: return "GX2_PERF_F32_TEX_BUSY"; // 9 case GX2_PERF_U64_VS_VERTICES_IN: return "GX2_PERF_U64_VS_VERTICES_IN"; // 10 case GX2_PERF_F32_VS_TEX_INST_COUNT: return "GX2_PERF_F32_VS_TEX_INST_COUNT"; // 11 case GX2_PERF_F32_VS_TEX_BUSY: return "GX2_PERF_F32_VS_TEX_BUSY"; // 12 case GX2_PERF_F32_VS_ALU_INST_COUNT: return "GX2_PERF_F32_VS_ALU_INST_COUNT"; // 13 case GX2_PERF_F32_VS_ALU_BUSY: return "GX2_PERF_F32_VS_ALU_BUSY"; // 14 case GX2_PERF_F32_VS_ALU_EFFICIENCY: return "GX2_PERF_F32_VS_ALU_EFFICIENCY"; // 15 case GX2_PERF_F32_VS_ALU_TEX_RATIO: return "GX2_PERF_F32_VS_ALU_TEX_RATIO"; // 16 case GX2_PERF_F32_GS_TEX_INST_COUNT: return "GX2_PERF_F32_GS_TEX_INST_COUNT"; // 17 case GX2_PERF_F32_GS_TEX_BUSY: return "GX2_PERF_F32_GS_TEX_BUSY"; // 18 case GX2_PERF_F32_GS_ALU_INST_COUNT: return "GX2_PERF_F32_GS_ALU_INST_COUNT"; // 19 case GX2_PERF_F32_GS_ALU_BUSY: return "GX2_PERF_F32_GS_ALU_BUSY"; // 20 case GX2_PERF_F32_GS_ALU_EFFICIENCY: return "GX2_PERF_F32_GS_ALU_EFFICIENCY"; // 21 case GX2_PERF_F32_GS_ALU_TEX_RATIO: return "GX2_PERF_F32_GS_ALU_TEX_RATIO"; // 22 case GX2_PERF_F32_PRIMITIVE_ASSEMBLY_BUSY: return "GX2_PERF_F32_PRIMITIVE_ASSEMBLY_BUSY"; // 23 case GX2_PERF_U64_PRIMITIVES_IN: return "GX2_PERF_U64_PRIMITIVES_IN"; // 24 case GX2_PERF_F32_PA_STALLED_ON_RASTERIZER: return "GX2_PERF_F32_PA_STALLED_ON_RASTERIZER"; // 25 case GX2_PERF_F32_INTERP_BUSY: return "GX2_PERF_F32_INTERP_BUSY"; // 26 case GX2_PERF_U64_PS_PIXELS_IN: return "GX2_PERF_U64_PS_PIXELS_IN"; // 27 case GX2_PERF_F32_PS_TEX_INST_COUNT: return "GX2_PERF_F32_PS_TEX_INST_COUNT"; // 28 case GX2_PERF_F32_PS_TEX_BUSY: return "GX2_PERF_F32_PS_TEX_BUSY"; // 29 case GX2_PERF_F32_PS_ALU_INST_COUNT: return "GX2_PERF_F32_PS_ALU_INST_COUNT"; // 30 case GX2_PERF_F32_PS_ALU_BUSY: return "GX2_PERF_F32_PS_ALU_BUSY"; // 31 case GX2_PERF_F32_PS_ALU_EFFICIENCY: return "GX2_PERF_F32_PS_ALU_EFFICIENCY"; // 32 case GX2_PERF_F32_PS_ALU_TEX_RATIO: return "GX2_PERF_F32_PS_ALU_TEX_RATIO"; // 33 case GX2_PERF_U64_PS_PIXELS_OUT: return "GX2_PERF_U64_PS_PIXELS_OUT"; // 34 case GX2_PERF_F32_PS_EXPORT_STALLS: return "GX2_PERF_F32_PS_EXPORT_STALLS"; // 35 case GX2_PERF_F32_TEX_UNIT_BUSY: return "GX2_PERF_F32_TEX_UNIT_BUSY"; // 36 case GX2_PERF_U64_TEXEL_FETCH_COUNT: return "GX2_PERF_U64_TEXEL_FETCH_COUNT"; // 37 case GX2_PERF_F32_TEX_CACHE_STALLED: return "GX2_PERF_F32_TEX_CACHE_STALLED"; // 38 case GX2_PERF_F32_TEX_MISS_RATE: return "GX2_PERF_F32_TEX_MISS_RATE"; // 39 case GX2_PERF_U64_TEX_MEM_BYTES_READ: return "GX2_PERF_U64_TEX_MEM_BYTES_READ"; // 40 case GX2_PERF_F32_DEPTH_STENCIL_TEST_BUSY: return "GX2_PERF_F32_DEPTH_STENCIL_TEST_BUSY"; // 41 case GX2_PERF_F32_HIZ_TRIVIAL_ACCEPT: return "GX2_PERF_F32_HIZ_TRIVIAL_ACCEPT"; // 42 case GX2_PERF_F32_HIZ_REJECT: return "GX2_PERF_F32_HIZ_REJECT"; // 43 case GX2_PERF_U64_PRE_Z_SAMPLES_PASSING: return "GX2_PERF_U64_PRE_Z_SAMPLES_PASSING"; // 44 case GX2_PERF_U64_PRE_Z_SAMPLES_FAILING_S: return "GX2_PERF_U64_PRE_Z_SAMPLES_FAILING_S"; // 45 case GX2_PERF_U64_PRE_Z_SAMPLES_FAILING_Z: return "GX2_PERF_U64_PRE_Z_SAMPLES_FAILING_Z"; // 46 case GX2_PERF_U64_POST_Z_SAMPLES_PASSING: return "GX2_PERF_U64_POST_Z_SAMPLES_PASSING"; // 47 case GX2_PERF_U64_POST_Z_SAMPLES_FAILING_S: return "GX2_PERF_U64_POST_Z_SAMPLES_FAILING_S"; // 48 case GX2_PERF_U64_POST_Z_SAMPLES_FAILING_Z: return "GX2_PERF_U64_POST_Z_SAMPLES_FAILING_Z"; // 49 case GX2_PERF_F32_Z_UNIT_STALLED: return "GX2_PERF_F32_Z_UNIT_STALLED"; // 50 case GX2_PERF_U64_PIXELS_AT_CB: return "GX2_PERF_U64_PIXELS_AT_CB"; // 51 case GX2_PERF_U64_PIXELS_CB_MEM_WRITTEN: return "GX2_PERF_U64_PIXELS_CB_MEM_WRITTEN"; // 52 case GX2_PERF_U64_IA_VERTICES: return "GX2_PERF_U64_IA_VERTICES"; // 53 case GX2_PERF_U64_IA_PRIMITIVES: return "GX2_PERF_U64_IA_PRIMITIVES"; // 54 case GX2_PERF_U64_VS_INVOCATIONS: return "GX2_PERF_U64_VS_INVOCATIONS"; // 55 case GX2_PERF_U64_GS_INVOCATIONS: return "GX2_PERF_U64_GS_INVOCATIONS"; // 56 case GX2_PERF_U64_GS_PRIMITIVES: return "GX2_PERF_U64_GS_PRIMITIVES"; // 57 case GX2_PERF_U64_C_INVOCATIONS: return "GX2_PERF_U64_C_INVOCATIONS"; // 58 case GX2_PERF_U64_C_PRIMITIVES: return "GX2_PERF_U64_C_PRIMITIVES"; // 59 case GX2_PERF_U64_PS_INVOCATIONS: return "GX2_PERF_U64_PS_INVOCATIONS"; // 60 case GX2_PERF_U64_PA_INPUT_PRIM: return "GX2_PERF_U64_PA_INPUT_PRIM"; // 61 default: ASSERT(!"GX2 perf table is out of sync" ); return GX2_INVALID_METRIC_NAME; } } /// \brief Returns the PerfMetric type given the PerfMetric /// \param metric metric ID /// /// \return metric type /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2PerfMetricType GX2API GX2GetPerfMetricType(GX2PerfMetric metric); /// \brief (deprecated) GX2 Temp API has been renamed. Use GX2GetPerfMetricType instead /// /// GX2TempGetPerfMetricType will be removed completely in a later SDK /// /// \donotcall \threadsafe \devonly \enddonotcall /// #define GX2TempGetPerfMetricType GX2GetPerfMetricType /// @} /// @addtogroup GX2PerfHighSetupGroup /// @{ #ifndef GX2_PERFORMANCE_DISABLED /// \brief Initialize a perf collection /// /// \param perfData Perf collection data /// \param maxTags Maximum number of tags in tag list /// \param pAllocator Allocation routines /// /// \donotcall \gx2_typical \userheap \enddonotcall /// void GX2API GX2PerfInit(GX2PerfData *perfData, u32 maxTags, MEMAllocator *pAllocator); /// \brief Free all memory used by the collection (incl. tag list) /// /// \note You must call GX2PerfInit again after making this call /// \param perfData Perf collection data /// /// \donotcall \gx2_typical \userheap \enddonotcall /// void GX2API GX2PerfFree(GX2PerfData *perfData); /// \brief Specify how tag results are collected /// /// \param perfData Perf collection data /// \param method Collection method /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2PerfSetCollectionMethod(GX2PerfData *perfData, GX2PerfCollectionMethod method); /// \brief Get current collection method /// /// \param perfData Perf collection data /// \return Currently set collection method /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2PerfCollectionMethod GX2API GX2PerfGetCollectionMethod(GX2PerfData *perfData); /// \brief Clear all metrics from the perf collection /// /// \param perfData Perf collection data /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2PerfMetricsClear(GX2PerfData *perfData); /// \brief Enable a desired metric /// /// \param perfData Perf collection data /// \param type Perf type - tells api how to interpret the 'id' parameter /// \param id a GX2PerfMetric if type is GX2_PERF_TYPE_GPU_METRIC or _GX2StatId if type is GX2_PERF_TYPE_GPU_STAT /// /// \return Returns false if metric could not be enabled when there are no available counter slots /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2Boolean GX2API GX2PerfMetricEnable(GX2PerfData *perfData, GX2PerfType type, u32 id); /// \brief Check if a specific metric/stat is enabled /// /// \param perfData Perf collection data /// \param type Metric type /// \param metricId Metric ID /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2Boolean GX2API GX2PerfMetricIsEnabled(GX2PerfData *perfData, GX2PerfType type, u32 metricId); /// \brief Iterate through enabled metrics /// /// \param perfData Perf collection data /// \param index Index of the desired metric /// \param type Metric type /// \param metricId Metric information /// /// \note To iterate through all metrics, start with index zero and increment /// index until the function returns GX2_FALSE /// /// \return Returns true if metric does not exceed number of metrics enabled /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2Boolean GX2API GX2PerfMetricGetEnabled(GX2PerfData *perfData, u32 index, GX2PerfType *type, u32 *metricId); // ----------------- // Tag Initialization /// \brief Enable a tag in the tag list /// /// \param perfData Perf collection data /// \param tag Tag to enable /// \param enable GX2_TRUE to enable, GX2_FALSE to disable /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2PerfTagEnable(GX2PerfData *perfData, GX2PerfTag tag, GX2Boolean enable); /// \brief Enable all tags in the tag list /// /// \param perfData Perf collection data /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2PerfTagEnableAll(GX2PerfData *perfData); /// \brief Disable all tags in the tag list /// /// \param perfData Perf collection data /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2PerfTagDisableAll(GX2PerfData *perfData); /// \brief Check if a tag is enabled in a tag list /// /// \param perfData Perf collection data /// \param tag Tag to check /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2Boolean GX2API GX2PerfTagIsEnabled(GX2PerfData *perfData, GX2PerfTag tag); /// @} /// @addtogroup GX2PerfHighCaptureGroup /// @{ // ----------------- // Run-time Frame Captures /// \brief Identify beginning of frame /// /// \note Once you call GX2PerfFrameStart, then you cannot change /// the enabled metrics or stats until after you call GX2PerfFrameEnd. /// Otherwise, the result size and offsets will not make any sense with the results. /// /// \param perfData Perf collection data /// /// \donotcall \gx2_typical \userheap \enddonotcall /// void GX2API GX2PerfFrameStart(GX2PerfData *perfData); /// \brief Identify end of frame /// /// \param perfData Perf collection data /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2PerfFrameEnd(GX2PerfData *perfData); /// \brief Get the number of passes needed based on the metrics which are enabled /// /// \param perfData Perf collection data /// /// \return Number of passes needed /// /// \donotcall \threadsafe \devonly \enddonotcall /// u32 GX2API GX2PerfGetNumPasses(GX2PerfData *perfData); /// \brief Configure counters for the current pass /// /// \param perfData Perf collection data /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2PerfPassStart(GX2PerfData *perfData); /// \brief Needs to be called at the end of a pass /// /// \param perfData Perf collection data /// /// /// \donotcall \gx2_typical \userheap \enddonotcall /// void GX2API GX2PerfPassEnd(GX2PerfData *perfData); /// \brief Mark the start of a user-defined section /// /// \param perfData Perf collection data /// \param tag Section tag /// /// \donotcall \gx2_typical \userheap \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2PerfTagStart(GX2PerfData *perfData, GX2PerfTag tag); /// \brief Mark the end of a user-defined section /// /// \param perfData Perf collection data /// \param tag Section tag /// /// \donotcall \gx2_typical \userheap \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2PerfTagEnd(GX2PerfData *perfData, GX2PerfTag tag); /// @} /// @addtogroup GX2PerfHighResultsGroup /// @{ // ----------------- // Results /// /// \brief Get a single per-frame metric result /// /// \param perfData Perf collection data /// \param type type of id (stat or metric) /// \param id Metric or Stat id /// \param pResult result /// /// \return Returns false if that metric was not enabled /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2Boolean GX2API GX2PerfGetResultByFrame(GX2PerfData *perfData, GX2PerfType type, u32 id, GX2MetricResult *pResult); /// /// \brief Get a single per-tag metric result, by specifying the tag info. /// /// \param perfData Perf collection data /// \param type Metric type /// \param id Metric id /// \param tag Tag id /// \param number Number of tag occurrence /// \param pResult Results /// /// \return Returns false if that metric was not enabled /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2Boolean GX2API GX2PerfGetResultByTagId(GX2PerfData *perfData, GX2PerfType type, u32 id, u32 tag, u32 number, GX2MetricResult *pResult); /// /// \brief Get a single per-tag metric result, by specifying the sequence #. /// /// \param perfData Perf collection data /// \param type Metric type /// \param id Metric id /// \param sequence Sequence number (0 = first tag result, 1 = second, and so on) /// \param tag Tag id /// \param number Number of metric /// \param depth Depth /// \param pResult Results /// /// \return Returns false if that metric was not enabled or if sequence # is beyond max /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2Boolean GX2API GX2PerfGetResultByTagSequence(GX2PerfData *perfData, GX2PerfType type, u32 id, u32 sequence, u32 *tag, u32 *number, u32 *depth, GX2MetricResult *pResult); /// \brief Convenience function to print results by frame /// /// \param perfData Perf collection data /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2PerfPrintFrameResults(GX2PerfData *perfData); /// \brief Convenience function to print results by tags /// /// \param perfData Perf collection data /// \param func Pointer to function that will convert tags to strings /// If func==NULL, just print tag numbers /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2PerfPrintTagResults(GX2PerfData *perfData, GX2PerfTag2StringFunc func); /// \brief Enable or disable the pass coherency checking. By default, pass coherency checking /// is disabled. /// /// \param perfData Perf collection data /// \param enable GX2_TRUE to enable, GX2_FALSE to disable /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2PerfSetPassCoherEnable(GX2PerfData *perfData, GX2Boolean enable); /// \brief Get the state of pass coherency checking /// /// \param perfData Perf collection data /// /// \return GX2_TRUE is enabled, GX2_FALSE if disabled /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2Boolean GX2API GX2PerfGetPassCoherEnable(GX2PerfData *perfData); #else GX2_INLINE void GX2PerfInit(GX2PerfData *perfData, u32 maxTags, MEMAllocator *pAllocator){ return; } GX2_INLINE void GX2PerfFree(GX2PerfData *perfData){ return; } GX2_INLINE void GX2PerfSetCollectionMethod(GX2PerfData *perfData, GX2PerfCollectionMethod method){ return; } GX2_INLINE GX2PerfCollectionMethod GX2PerfGetCollectionMethod(GX2PerfData *perfData){ return GX2_PERF_COLLECT_NONE; } GX2_INLINE void GX2PerfMetricsClear(GX2PerfData *perfData){ return; } GX2_INLINE GX2Boolean GX2PerfMetricEnable(GX2PerfData *perfData, GX2PerfType type, u32 id){ return GX2_TRUE; } GX2_INLINE GX2Boolean GX2PerfMetricIsEnabled(GX2PerfData *perfData, GX2PerfType type, u32 metricId){ return GX2_FALSE; } GX2_INLINE GX2Boolean GX2PerfMetricGetEnabled(GX2PerfData *perfData, u32 index, GX2PerfType *type, u32 *metricId){ return GX2_FALSE; } GX2_INLINE void GX2PerfTagEnable(GX2PerfData *perfData, GX2PerfTag tag, GX2Boolean enable){ return; } GX2_INLINE void GX2PerfTagEnableAll(GX2PerfData *perfData){ return; } GX2_INLINE void GX2PerfTagDisableAll(GX2PerfData *perfData){ return; } GX2_INLINE GX2Boolean GX2PerfTagIsEnabled(GX2PerfData *perfData, GX2PerfTag tag){ return GX2_FALSE; } GX2_INLINE void GX2PerfFrameStart(GX2PerfData *perfData){ return; } GX2_INLINE void GX2PerfFrameEnd(GX2PerfData *perfData){ return; } GX2_INLINE u32 GX2PerfGetNumPasses(GX2PerfData *perfData){ return 0; } GX2_INLINE void GX2PerfPassStart(GX2PerfData *perfData){ return; } GX2_INLINE void GX2PerfPassEnd(GX2PerfData *perfData){ return; } GX2_INLINE void GX2PerfTagStart(GX2PerfData *perfData, GX2PerfTag tag){ return; } GX2_INLINE void GX2PerfTagEnd(GX2PerfData *perfData, GX2PerfTag tag){ return; } GX2_INLINE GX2Boolean GX2PerfGetResultByFrame(GX2PerfData *perfData, GX2PerfType type, u32 id, GX2MetricResult *pResult){ return GX2_FALSE; } GX2_INLINE GX2Boolean GX2PerfGetResultByTagId(GX2PerfData *perfData, GX2PerfType type, u32 id, u32 tag, u32 number, GX2MetricResult *pResult){ return GX2_FALSE; } GX2_INLINE GX2Boolean GX2PerfGetResultByTagSequence(GX2PerfData *perfData, GX2PerfType type, u32 id, u32 sequence, u32 *tag, u32 *number, u32 *depth, GX2MetricResult *pResult){ return GX2_FALSE; } GX2_INLINE void GX2PerfPrintFrameResults(GX2PerfData *perfData){ return; } GX2_INLINE void GX2PerfPrintTagResults(GX2PerfData *perfData, GX2PerfTag2StringFunc func){ return; } GX2_INLINE void GX2PerfSetPassCoherEnable(GX2PerfData *perfData, GX2Boolean enable){ return; } GX2_INLINE GX2Boolean GX2PerfGetPassCoherEnable(GX2PerfData *perfData) { return GX2_FALSE; } #endif /// @} #ifdef __cplusplus } #endif #endif /// _CAFE_GX2_PERF2_H_