1 /*---------------------------------------------------------------------------*
2
3 Copyright (C) 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 timestamp-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 given address.
62 ///
63 /// This action is asynchronous to the CPU. The CPU will write the
64 /// value GX2_INVALID_COUNTER_VALUE_U64 to the given 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 given address.
79 ///
80 /// This action is asynchronous to the CPU. The CPU will write the
81 /// value GX2_INVALID_COUNTER_VALUE_U64 to the given 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 given 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 given 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