/*---------------------------------------------------------------------------* 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. *---------------------------------------------------------------------------*/ // gx2Query.h // // Declares Query APIs for gx2 library. #ifndef _CAFE_GX2_QUERY_H_ #define _CAFE_GX2_QUERY_H_ #ifdef __cplusplus extern "C" { #endif // __cplusplus /// @addtogroup GX2QueryGroup /// @{ // ----------------- // Query /// \brief Structure for GPU to store query data in. /// typedef struct _GX2QueryInfo { /// Hardware registers written by query /// (in little-endian format) u64 _reg[8]; } GX2QueryInfo; /// @} /// @addtogroup GX2PerfCycleGroup /// @{ /// \brief Check if cycle data is written by GPU yet. /// /// \note It is perhaps better to use a time stamp-based synchronization method. /// /// \param addr User-allocated buffer where GPU will write cycle result /// /// \donotcall \fgonly \notthreadsafe notinterrupt \notexception \devonly \enddonotcall /// GX2_INLINE GX2Boolean GX2GetGPUCycleReady(const u64* addr) { GX2Invalidate(GX2_INVALIDATE_CPU, (void *)addr, sizeof(u64)); return (GX2Boolean)(*addr != GX2_INVALID_COUNTER_VALUE_U64); } /// \brief Requests the GPU to write out its /// constantly running cycle counter immediately (at the top of the /// graphics pipeline) into the specified address. /// /// This action is asynchronous to the CPU. The CPU will write the /// value GX2_INVALID_COUNTER_VALUE_U64 to the specified address initially. /// /// \param addr Address where 64-bit GPU cycle count will be written into. /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SampleTopGPUCycle(u64* addr); /// \brief Requests the GPU to forward this command through /// the entire GPU pipeline, and only at the end (at the bottom of the /// graphics pipeline), write out its constantly running cycle /// counter into the specified address. /// /// This action is asynchronous to the CPU. The CPU will write the /// value GX2_INVALID_COUNTER_VALUE_U64 to the specified address initially. /// /// \param addr Address where 64-bit GPU cycle count will be written into. /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SampleBottomGPUCycle(u64* addr); /// \brief Convert CPU time into GPU time /// /// This is used to convert the CPU's tick counter into values that can /// be compared with the GPU's constantly running cycle counter. /// /// \param cputime CPU OSTick-based time /// \return similar value in GPU cycle-counter-based time /// /// \donotcall \threadsafe \devonly \enddonotcall /// u64 GX2API GX2CPUTimeToGPUTime(u64 cputime); /// \brief Convert GPU time into CPU time /// /// This is used to convert the GPU's constantly running cycle counter /// into values that can be compared with the CPU's tick counter. /// /// \param gputime GPU cycle-counter-based time /// \return similar value in CPU OSTick-based time /// /// \donotcall \threadsafe \devonly \enddonotcall /// u64 GX2API GX2GPUTimeToCPUTime(u64 gputime); /// @} /// @addtogroup GX2QueryGroup /// @{ /// \brief Start the requested query operation. /// Requests the GPU start the query operation and write the beginning values to the specified buffer. /// /// This action is asynchronous to the CPU. /// /// \param type Specifies the type of query /// \param queryinfo User-allocated data structure where the query data is written by GPU. /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2QueryBegin(GX2QueryType type, GX2QueryInfo* queryinfo); /// \brief Finish the requested query operation. /// Requests the GPU to write the end values to the specified buffer /// /// This action is asynchronous to the CPU. /// /// \note It takes time for the query data to be written out, and other /// GPU processing may (should) be done during this time. /// /// \note This function must be called before calling any APIs that read the query results /// /// \param type Specifies the type of query /// \param queryinfo User-allocated data structure where the query data is written by GPU. /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2QueryEnd(GX2QueryType type, GX2QueryInfo* queryinfo); /// \brief Retrieve the occlusion query result /// /// \param queryinfo user-allocated data structure where the query data is written by GPU. /// \param pZPass pointer to the buffer to return the Z pass count /// \return GX2_TRUE if the occlusion results are available, GX2_FALSE if the data is not available /// /// \donotcall \fgonly \notthreadsafe \devonly \enddonotcall /// GX2Boolean GX2API GX2QueryGetOcclusionResult(const GX2QueryInfo* queryinfo, u64* pZPass); typedef struct _GX2StreamOutStats { u64 primitivesWritten; // Number of primitives written to the stream out buffer u64 storageNeeded; // The amount of storage (in primitives) needed in the stream out buffer } GX2StreamOutStats; /// \brief Retrieve the stream out stats query results /// /// \param queryinfo user-allocated data structure where the query data is written by GPU. /// \param pStats pointer to the buffer to return the stream out stats. /// \return GX2_TRUE if the stream out stats are available, GX2_FALSE if the data is not available /// /// \donotcall \fgonly \notthreadsafe \devonly \enddonotcall /// GX2Boolean GX2API GX2QueryGetStreamOutStatsResult( const GX2QueryInfo* queryinfo, GX2StreamOutStats* pStats); /// \brief Start conditional rendering based on the results of a GX2 query. /// /// \note The hint parameter is only used for the occlusion query. The GPU will always wait /// for the stream out stats result. /// /// \param type Specifies the type of query /// \param queryinfo Same data structure that was used with the preceding query. /// \param hint If GX2_FALSE, waits until occlusion query results are ready before continuing; /// if GX2_TRUE, checks once and obeys occlusion query results if they are ready, or just draws otherwise. /// \param predicate If GX2_FALSE, enables drawing if no pixels visible/stream out buffer overflow /// If GX2_TRUE, enables drawing if pixels visible/no stream out buffer overflow /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2QueryBeginConditionalRender(GX2QueryType type, const GX2QueryInfo* queryinfo, GX2Boolean hint, GX2Boolean predicate); /// \brief End conditional rendering. /// /// After issuing this command, future drawing does not depend upon the query results. /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2QueryEndConditionalRender(void); /// @} #ifdef __cplusplus } #endif // __cplusplus #endif // _CAFE_GX2_MISC_H_