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