1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: demo_CommandListSwapper.h 4 5 Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain proprietary 8 information of Nintendo and/or its licensed developers and are protected by 9 national and international copyright laws. They may not be disclosed to third 10 parties or copied or duplicated in any form, in whole or in part, without the 11 prior written consent of Nintendo. 12 13 The content herein is highly confidential and should be handled accordingly. 14 15 $Revision: 31311 $ 16 *---------------------------------------------------------------------------*/ 17 #ifndef NW_DEMO_COMMANDLISTSWAPPER_H_ 18 #define NW_DEMO_COMMANDLISTSWAPPER_H_ 19 20 #include <GLES2/gl2.h> 21 22 #include <nw/ut/ut_MoveArray.h> 23 #include <nn/gx.h> 24 #include <nn/os.h> 25 26 namespace nw 27 { 28 namespace os 29 { 30 class IAllocator; 31 } 32 33 namespace demo 34 { 35 //--------------------------------------------------------------------------- 36 //! @brief コマンドリストとそのバッファリングを管理するクラスです。 37 //--------------------------------------------------------------------------- 38 class CommandListSwapper 39 { 40 NW_DISALLOW_COPY_AND_ASSIGN(CommandListSwapper); 41 42 public: 43 44 //--------------------------------------------------------------------------- 45 //! @brief コマンドリストスワッパーの設定内容です。 46 //--------------------------------------------------------------------------- 47 struct Description 48 { 49 size_t commandListCount; //!< 生成するコマンドリストの数です。 50 size_t bufferSize; //!< 1つのコマンドリストのバッファサイズです。 51 size_t requestCount; //!< 1つのコマンドリクエストの上限数です。 52 size_t reusableBufferSize; //!< 1つの再利用コマンドリストのコマンドバッファのサイズを表します。 53 size_t reusableRequestCount; //!< 1つの再利用コマンドリストのコマンドリクエストの上限数です。 54 size_t maxGpuProfilingEntryCount; //!< GPU プロファイルエントリの上限数です。 55 }; 56 57 //---------------------------------------- 58 //! @name 生成/破棄 59 //@{ 60 61 //! @brief コマンドリストスワッパーを作成します。 62 //! 63 //! @param[in] allocator アロケータです 64 //! @param[in] description 生成するコマンドリストスワッパーの設定です。 65 //! 66 static CommandListSwapper* Create(os::IAllocator* allocator, Description& description); 67 68 //! @brief 破棄します。 69 void Destroy(); 70 71 //@} 72 73 //---------------------------------------- 74 //! @name 操作 75 //@{ 76 77 //! @brief コマンドリストをバインドします。 78 void Bind(); 79 80 //! @brief バインドされているコマンドリストを実行します。 Run()81 void Run() 82 { 83 RunAsync(); 84 WaitDone(); 85 } 86 87 //! @brief バインドされているコマンドリストを非同期で実行します。 88 void RunAsync(); 89 90 //! @brief 非同期で実行したコマンドリストの終了待ちをします。 91 void WaitDone(); 92 93 //! @brief コマンドリストをスワップします。 94 //! 95 //! この関数だけではバインドされないので注意してください。 96 void Swap(); 97 98 //@} 99 100 //---------------------------------------- 101 //! @name GPU プロファイリング 102 //@{ 103 104 //! @brief GPU プロファイラをリセットします。 105 //! 106 //! バインドされているコマンドリストに追加された GPU プロファイルエントリをすべて削除します。 107 //! コマンドリストが多重化されている場合はコマンドリストをスワップするときに、 108 //! そうでない場合は終了待ちの直後に自動で呼ばれるため、手動でこの関数を実行する必要はありません。 109 //! 110 //! @sa Swap 111 //! @sa WaitDone 112 void ResetGpuProfiling(); 113 114 //! @brief コマンドリストの GPU プロファイルエントリを追加し、始点を設定します。 115 //! 116 //! コマンドリストの実行時間を計測する GPU プロファイラのエントリをバインドされているコマンドリストに追加し、 117 //! その始点をこの関数が実行された時点で最後に蓄積されたコマンドリクエストの終了時に設定します。 118 //! 119 //! この関数は 3D コマンドバッファを区切らないので、必要に応じて nngxSplitCmdlist() 関数を呼び出してください。 120 //! 121 //! 複数の CommandListSwapper インスタンスから GPU プロファイルを行うことはできません。 122 //! 123 //! エントリの追加に失敗した場合、負の値が返されます。 124 //! 125 //! @param IsInTotal この引数に true を設定すると、この GPU プロファイルエントリを GetGpuProfilingTotalCostTime() での計算に含めます。 126 //! 127 //! @return 追加された GPU プロファイルエントリの番号を返します。 128 //! 129 //! @sa SetGpuProfilingEndPoint 130 //! @sa GetGpuProfilingTotalCostTime 131 s32 AddGpuProfilingStartPoint(bool IsInTotal); 132 133 //! @brief GPU プロファイルエントリの終点を設定します。 134 //! 135 //! 指定した GPU プロファイルエントリの終点を 136 //! この関数が実行された時点で最後に蓄積されたコマンドリクエストの終了時に設定します。 137 //! 計測された実行時間を取得するには GetGpuProfilingCostTime() や GetGpuProfilingTotalCostTime() を使用します。 138 //! 139 //! この関数は 3D コマンドバッファを区切らないので、必要に応じて nngxSplitCmdlist() 関数を呼び出してください。 140 //! 141 //! 複数の CommandListSwapper インスタンスから GPU プロファイルを行うことはできません。 142 //! 143 //! @param profilingId AddGpuProfilerStartPoint() で返されたエントリの番号を指定します。 144 //! 145 //! @sa AddGpuProfilingStartPoint 146 //! @sa GetGpuProfilingTotalCostTime 147 void SetGpuProfilingEndPoint(u32 profilingId); 148 149 //! @brief 計測された GPU プロファイルエントリの実行時間を取得します。 150 //! 151 //! 実行されたコマンドリストに追加された GPU プロファイルエントリの実行時間をミリ秒単位で取得します。 152 //! この関数で実行時間を取得する前に、WaitDone() によりコマンドリストの終了待ちをする必要があります。 153 //! 指定した番号のエントリが存在しない場合、この関数は 0.0f を返します。 154 //! 155 //! コマンドリストが多重化されている場合は Swap() 実行時に、 156 //! そうでない場合は Run() 実行時に GPU プロファイルの結果が失われます。 157 //! 158 //! 得られる GPU プロファイルエントリの結果はバインドされているコマンドリストではなく、 159 //! WaitDone() で終了待ちをしたコマンドリストが対象であることに注意してください。 160 //! 161 //! @param profilingId AddGpuProfilingStartPoint() で返されたエントリの番号を指定します。 162 //! 163 //! @return ミリ秒単位の実行時間です。 164 //! 165 //! @sa AddGpuProfilingStartPoint 166 //! @sa GetGpuProfilingTotalCostTime 167 f32 GetGpuProfilingCostTime(u32 profilingId); 168 169 //! @brief GPU プロファイルエントリの合計実行時間を取得します。 170 //! 171 //! AddGpuProfilerStartPoint() で、引数 IsInTotal に true を指定した GPU プロファイルエントリの合計実行時間をミリ秒単位で取得します。 172 //! 実行区間が重複している GPU プロファイルエントリについても単純に加算されますので注意してください。 173 //! 174 //! コマンドリストが多重化されている場合は Swap() 実行時に、 175 //! そうでない場合は Run() 実行時に GPU プロファイルの結果が失われます。 176 //! 177 //! 得られる GPU プロファイルエントリの結果はバインドされているコマンドリストではなく、 178 //! WaitDone() で終了待ちをしたコマンドリストが対象であることに注意してください。 179 //! 180 //! @return ミリ秒単位の実行時間です。 181 //! 182 //! @sa AddGpuProfilingStartPoint 183 //! @sa GetGpuProfilingCostTime 184 f32 GetGpuProfilingTotalCostTime(); 185 186 //} 187 188 //---------------------------------------- 189 //! @name 取得/設定 190 //@{ 191 192 //! @brief コマンドリストの ID を取得します。 GetCommandListId()193 GLuint GetCommandListId() const { return m_CommandLists[m_BoundIndex]; } 194 195 //! @brief コマンドリストの数を取得します。 GetListCount()196 size_t GetListCount() const { return this->m_CommandLists.size(); } 197 198 //! @brief 蓄積された 3D コマンドバッファのサイズを取得します。 199 //! 200 //! 現在バインドされているコマンドリストの 3D コマンドバッファのサイズを 201 //! バイト単位で取得します。 202 //! 203 //! 再利用するために保存されたコマンドリストの 3D コマンドバッファのサイズを求めるときは 204 //! GetReusableCommandBufferSize を使用してください。 205 //! 206 //! @return 3D コマンドバッファのサイズをバイト単位で返します。 207 //! 208 //! @sa GetReusableCommandBufferSize 209 int GetCommandBufferSize() const; 210 211 //! @brief 再利用するために保存されたコマンドリストの 3D コマンドバッファのサイズを取得します。 212 //! 213 //! 再利用するために保存されたコマンドリストの 3D コマンドバッファのサイズを 214 //! バイト単位で取得します。 215 //! 216 //! 現在バインドされているコマンドリストの 3D コマンドバッファのサイズを求めるときは 217 //! GetCommandBufferSize を使用してください。 218 //! 219 //! また、StartCommandSave と EndCommandSave の間で再利用するコマンドのサイズを取得するときは、 220 //! GetCommandBufferSize を使用してください。StartCommandSave で再利用するためのコマンドリストがバインドされるためです。 221 //! 222 //! @return 3D コマンドバッファのサイズをバイト単位で返します。 223 //! 224 //! @sa GetCommandBufferSize 225 //! @sa StartCommandSave 226 int GetReusableCommandBufferSize() const; 227 228 //@} 229 230 //---------------------------------------- 231 //! @name コマンドの再利用 232 //@{ 233 234 //! @brief 再利用するコマンドの保存を開始します。 235 //! 236 //! 再利用するためのコマンドリストをバインドし、コマンドの保存を開始します。 237 //! 保存は EndSaving() が実行されるまで行われます。 238 //! 保存されたコマンドは ReuseCommand() で再利用することができます。 239 //! 240 //! コマンドの再利用を有効にするためには Create() の引数である Description 構造体の 241 //! メンバ reusableListBufferSize と reusableListRequestCount に正の値を設定します。 242 //! 243 //! @sa EndCommandSave 244 //! @sa ReuseCommand 245 void StartCommandSave(); 246 247 //! @brief 再利用するコマンドの保存を終了します。 248 //! 249 //! コマンドの保存を終了し、コマンドリストをバインドしなおします。 250 //! 251 //! @sa StartCommandSave 252 //! @sa ReuseCommand 253 void EndCommandSave(); 254 255 //! @brief 保存されたコマンドを再利用します。 256 //! 257 //! StartCommandSave() と EndCommandSave() により保存されたコマンドをバインドされているコマンドリストへ追加します。 258 //! isCopyBuffer に true を指定した場合はコマンドがコピーされて追加されます。 259 //! false を指定した場合は、3D コマンドバッファは保存されたコマンドを参照します。 260 //! 詳細は CTR-SDK の nngxUseSavedCmdlist 関数を参照してください。 261 //! 262 //! @param[in] isCopyBuffer バッファをコピーするかを指定します。 263 //! 264 //! @sa StartCommandSave 265 //! @sa EndCommandSave 266 void ReuseCommand(bool isCopyBuffer); 267 268 //@} 269 270 private: 271 CommandListSwapper(os::IAllocator* allocator, Description& description); 272 ~CommandListSwapper()273 ~CommandListSwapper() {} 274 275 //! @brief GPU プロファイルエントリの実行時間を計算します。 276 void CalcGpuProfilingCostTime(); 277 278 //! @brief コマンドリストの実行時間を計測するためにシステムチックを記録します。 279 void SetGpuProfilingTick(GLint id); 280 281 //! @brief 登録されるコールバック関数です。 282 static void CommandListCallback(GLint id); 283 284 //! @brief コールバックを登録します。 285 //! 286 //! @return コールバックが登録されたコマンドリクエストの番号を返します。 287 GLuint RegisterCallback(); 288 289 //! @brief コマンドリスト実行完了待ちがタイムアウトした際に呼び出されるコールバック関数です。 290 static void TimeoutWaitCommandListDone(); 291 292 //! @brief コマンドリストのパラメータをログに出力します。 293 void DumpCommandListParameter(); 294 295 struct GpuProfilingEntry { 296 GLuint beginId; 297 GLuint endId; 298 299 s64 beginTick; 300 s64 endTick; 301 302 f32 costTime; 303 304 bool isInTotal; 305 GpuProfilingEntryGpuProfilingEntry306 GpuProfilingEntry() 307 : beginId(0), 308 endId(0), 309 beginTick(0), 310 endTick(0), 311 costTime(0.0f), 312 isInTotal(false) 313 {} 314 }; 315 316 os::IAllocator* m_Allocator; 317 typedef ut::MoveArray<GLuint> CommandListArray; 318 CommandListArray m_CommandLists; 319 int m_BoundIndex; 320 321 int m_RunningIndex; 322 bool m_IsRunning; 323 324 typedef ut::MoveArray<GpuProfilingEntry> GpuProfilingEntryArray; 325 GpuProfilingEntryArray m_GpuProfilingEntries; 326 GpuProfilingEntryArray m_GpuProfilingResults; 327 328 CommandListArray m_ReusableCommandLists; 329 GLuint m_ReusableBufferOffset; 330 GLsizei m_ReusableBufferSize; 331 GLuint m_ReusableRequestId; 332 GLsizei m_ReusableRequestSize; 333 334 u8* m_DumpCommandListBuffer; 335 static const s64 COMMAND_LIST_WAIT_TIME_OUT; 336 337 static CommandListSwapper* s_CommandListSwapper; 338 }; 339 340 } // namespace demo 341 } // namespace nw 342 343 #endif // NW_DEMO_COMMANDLISTSWAPPER_H_ 344