1 /*---------------------------------------------------------------------------*
2 
3   Copyright (C) 2010-2011 Nintendo.  All rights reserved.
4 
5   These coded instructions, statements, and computer programs contain
6   proprietary information of Nintendo of America Inc. and/or Nintendo
7   Company Ltd., and are protected by Federal copyright law.  They may
8   not be disclosed to third parties or copied or duplicated in any form,
9   in whole or in part, without the prior written consent of Nintendo.
10 
11  *---------------------------------------------------------------------------*/
12 
13 // gx2Query.h
14 //
15 // Declares Query APIs for gx2 library.
16 
17 #ifndef _CAFE_GX2_QUERY_H_
18 #define _CAFE_GX2_QUERY_H_
19 
20 #ifdef __cplusplus
21 extern "C"
22 {
23 #endif // __cplusplus
24 
25 /// @addtogroup GX2QueryGroup
26 /// @{
27 
28 // -----------------
29 // Query
30 
31 /// \brief Structure for GPU to store query data in.
32 ///
33 typedef struct _GX2QueryInfo
34 {
35     /// Hardware registers written by query
36     /// (in little-endian format)
37     u64 _reg[8];
38 
39 } GX2QueryInfo;
40 
41 /// @}
42 /// @addtogroup GX2PerfCycleGroup
43 /// @{
44 
45 /// \brief Check if cycle data is written by GPU yet.
46 ///
47 /// \note It is perhaps better to use a time stamp-based synchronization method.
48 ///
49 /// \param addr User-allocated buffer where GPU will write cycle result
50 ///
51 /// \donotcall \fgonly \notthreadsafe notinterrupt \notexception \devonly \enddonotcall
52 ///
GX2GetGPUCycleReady(const u64 * addr)53 GX2_INLINE GX2Boolean GX2GetGPUCycleReady(const u64* addr)
54 {
55     GX2Invalidate(GX2_INVALIDATE_CPU, (void *)addr, sizeof(u64));
56     return (GX2Boolean)(*addr != GX2_INVALID_COUNTER_VALUE_U64);
57 }
58 
59 /// \brief Requests the GPU to write out its
60 /// constantly running cycle counter immediately (at the top of the
61 /// graphics pipeline) into the specified address.
62 ///
63 /// This action is asynchronous to the CPU.  The CPU will write the
64 /// value GX2_INVALID_COUNTER_VALUE_U64 to the specified address initially.
65 ///
66 /// \param addr Address where 64-bit GPU cycle count will be written into.
67 ///
68 /// \donotcall \gx2_typical \enddonotcall
69 ///
70 /// \writesgpu
71 /// \alwayswritesgpu
72 ///
73 void GX2API GX2SampleTopGPUCycle(u64* addr);
74 
75 /// \brief Requests the GPU to forward this command through
76 /// the entire GPU pipeline, and only at the end (at the bottom of the
77 /// graphics pipeline), write out its constantly running cycle
78 /// counter into the specified address.
79 ///
80 /// This action is asynchronous to the CPU.  The CPU will write the
81 /// value GX2_INVALID_COUNTER_VALUE_U64 to the specified address initially.
82 ///
83 /// \param addr Address where 64-bit GPU cycle count will be written into.
84 ///
85 /// \donotcall \gx2_typical \enddonotcall
86 ///
87 /// \writesgpu
88 /// \alwayswritesgpu
89 ///
90 void GX2API GX2SampleBottomGPUCycle(u64* addr);
91 
92 /// \brief Convert CPU time into GPU time
93 ///
94 /// This is used to convert the CPU's tick counter into values that can
95 /// be compared with the GPU's constantly running cycle counter.
96 ///
97 /// \param cputime CPU OSTick-based time
98 /// \return similar value in GPU cycle-counter-based time
99 ///
100 /// \donotcall \threadsafe \devonly \enddonotcall
101 ///
102 u64 GX2API GX2CPUTimeToGPUTime(u64 cputime);
103 
104 /// \brief Convert GPU time into CPU time
105 ///
106 /// This is used to convert the GPU's constantly running cycle counter
107 /// into values that can be compared with the CPU's tick counter.
108 ///
109 /// \param gputime GPU cycle-counter-based time
110 /// \return similar value in CPU OSTick-based time
111 ///
112 /// \donotcall \threadsafe \devonly \enddonotcall
113 ///
114 u64 GX2API GX2GPUTimeToCPUTime(u64 gputime);
115 
116 /// @}
117 /// @addtogroup GX2QueryGroup
118 /// @{
119 
120 /// \brief Start the requested query operation.
121 /// Requests the GPU start the query operation and write the beginning values to the specified buffer.
122 ///
123 /// This action is asynchronous to the CPU.
124 ///
125 /// \param type  Specifies the type of query
126 /// \param queryinfo User-allocated data structure where the query data is written by GPU.
127 ///
128 /// \donotcall \gx2_typical \enddonotcall
129 ///
130 /// \writesgpu
131 /// \alwayswritesgpu
132 ///
133 void GX2API GX2QueryBegin(GX2QueryType type, GX2QueryInfo* queryinfo);
134 
135 /// \brief Finish the requested query operation.
136 /// Requests the GPU to write the end values to the specified buffer
137 ///
138 /// This action is asynchronous to the CPU.
139 ///
140 /// \note It takes time for the query data to be written out, and other
141 /// GPU processing may (should) be done during this time.
142 ///
143 /// \note This function must be called before calling any APIs that read the query results
144 ///
145 /// \param type  Specifies the type of query
146 /// \param queryinfo User-allocated data structure where the query data is written by GPU.
147 ///
148 /// \donotcall \gx2_typical \enddonotcall
149 ///
150 /// \writesgpu
151 /// \alwayswritesgpu
152 ///
153 void GX2API GX2QueryEnd(GX2QueryType type, GX2QueryInfo* queryinfo);
154 
155 /// \brief Retrieve the occlusion query result
156 ///
157 /// \param queryinfo user-allocated data structure where the query data is written by GPU.
158 /// \param pZPass  pointer to the buffer to return the Z pass count
159 /// \return GX2_TRUE if the occlusion results are available, GX2_FALSE if the data is not available
160 ///
161 /// \donotcall \fgonly \notthreadsafe \devonly \enddonotcall
162 ///
163 GX2Boolean GX2API GX2QueryGetOcclusionResult(const GX2QueryInfo* queryinfo, u64* pZPass);
164 
165 typedef struct _GX2StreamOutStats
166 {
167     u64 primitivesWritten; // Number of primitives written to the stream out buffer
168     u64 storageNeeded;     // The amount of storage (in primitives) needed in the stream out buffer
169 
170 } GX2StreamOutStats;
171 
172 /// \brief Retrieve the stream out stats query results
173 ///
174 /// \param queryinfo user-allocated data structure where the query data is written by GPU.
175 /// \param pStats    pointer to the buffer to return the stream out stats.
176 /// \return GX2_TRUE if the stream out stats are available, GX2_FALSE if the data is not available
177 ///
178 /// \donotcall \fgonly \notthreadsafe \devonly \enddonotcall
179 ///
180 GX2Boolean GX2API GX2QueryGetStreamOutStatsResult(
181     const GX2QueryInfo* queryinfo,
182     GX2StreamOutStats* pStats);
183 
184 
185 /// \brief Start conditional rendering based on the results of a GX2 query.
186 ///
187 /// \note The hint parameter is only used for the occlusion query.   The GPU will always wait
188 /// for the stream out stats result.
189 ///
190 /// \param type  Specifies the type of query
191 /// \param queryinfo Same data structure that was used with the preceding query.
192 /// \param hint If GX2_FALSE, waits until occlusion query results are ready before continuing;
193 ///             if GX2_TRUE, checks once and obeys occlusion query results if they are ready, or just draws otherwise.
194 /// \param predicate If GX2_FALSE, enables drawing if no pixels visible/stream out buffer overflow
195 ///                  If GX2_TRUE, enables drawing if pixels visible/no stream out buffer overflow
196 ///
197 /// \donotcall \gx2_typical \enddonotcall
198 ///
199 /// \writesgpu
200 /// \alwayswritesgpu
201 ///
202 void GX2API GX2QueryBeginConditionalRender(GX2QueryType type,
203                                            const GX2QueryInfo* queryinfo,
204                                            GX2Boolean hint,
205                                            GX2Boolean predicate);
206 
207 /// \brief End conditional rendering.
208 ///
209 /// After issuing this command, future drawing does not depend upon the query results.
210 ///
211 /// \donotcall \gx2_typical \enddonotcall
212 ///
213 /// \writesgpu
214 /// \alwayswritesgpu
215 ///
216 void GX2API GX2QueryEndConditionalRender(void);
217 
218 /// @}
219 
220 #ifdef __cplusplus
221 }
222 #endif // __cplusplus
223 
224 #endif // _CAFE_GX2_MISC_H_
225