/*---------------------------------------------------------------------------* Project: NintendoWare File: demo_CommandListSwapper.h Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo and/or its licensed developers and are protected by national and international copyright laws. 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. The content herein is highly confidential and should be handled accordingly. $Revision: 31311 $ *---------------------------------------------------------------------------*/ #ifndef NW_DEMO_COMMANDLISTSWAPPER_H_ #define NW_DEMO_COMMANDLISTSWAPPER_H_ #include #include #include #include namespace nw { namespace os { class IAllocator; } namespace demo { //--------------------------------------------------------------------------- //! @brief コマンドリストとそのバッファリングを管理するクラスです。 //--------------------------------------------------------------------------- class CommandListSwapper { NW_DISALLOW_COPY_AND_ASSIGN(CommandListSwapper); public: //--------------------------------------------------------------------------- //! @brief コマンドリストスワッパーの設定内容です。 //--------------------------------------------------------------------------- struct Description { size_t commandListCount; //!< 生成するコマンドリストの数です。 size_t bufferSize; //!< 1つのコマンドリストのバッファサイズです。 size_t requestCount; //!< 1つのコマンドリクエストの上限数です。 size_t reusableBufferSize; //!< 1つの再利用コマンドリストのコマンドバッファのサイズを表します。 size_t reusableRequestCount; //!< 1つの再利用コマンドリストのコマンドリクエストの上限数です。 size_t maxGpuProfilingEntryCount; //!< GPU プロファイルエントリの上限数です。 }; //---------------------------------------- //! @name 生成/破棄 //@{ //! @brief コマンドリストスワッパーを作成します。 //! //! @param[in] allocator アロケータです //! @param[in] description 生成するコマンドリストスワッパーの設定です。 //! static CommandListSwapper* Create(os::IAllocator* allocator, Description& description); //! @brief 破棄します。 void Destroy(); //@} //---------------------------------------- //! @name 操作 //@{ //! @brief コマンドリストをバインドします。 void Bind(); //! @brief バインドされているコマンドリストを実行します。 void Run() { RunAsync(); WaitDone(); } //! @brief バインドされているコマンドリストを非同期で実行します。 void RunAsync(); //! @brief 非同期で実行したコマンドリストの終了待ちをします。 void WaitDone(); //! @brief コマンドリストをスワップします。 //! //! この関数だけではバインドされないので注意してください。 void Swap(); //@} //---------------------------------------- //! @name GPU プロファイリング //@{ //! @brief GPU プロファイラをリセットします。 //! //! バインドされているコマンドリストに追加された GPU プロファイルエントリをすべて削除します。 //! コマンドリストが多重化されている場合はコマンドリストをスワップするときに、 //! そうでない場合は終了待ちの直後に自動で呼ばれるため、手動でこの関数を実行する必要はありません。 //! //! @sa Swap //! @sa WaitDone void ResetGpuProfiling(); //! @brief コマンドリストの GPU プロファイルエントリを追加し、始点を設定します。 //! //! コマンドリストの実行時間を計測する GPU プロファイラのエントリをバインドされているコマンドリストに追加し、 //! その始点をこの関数が実行された時点で最後に蓄積されたコマンドリクエストの終了時に設定します。 //! //! この関数は 3D コマンドバッファを区切らないので、必要に応じて nngxSplitCmdlist() 関数を呼び出してください。 //! //! 複数の CommandListSwapper インスタンスから GPU プロファイルを行うことはできません。 //! //! エントリの追加に失敗した場合、負の値が返されます。 //! //! @param IsInTotal この引数に true を設定すると、この GPU プロファイルエントリを GetGpuProfilingTotalCostTime() での計算に含めます。 //! //! @return 追加された GPU プロファイルエントリの番号を返します。 //! //! @sa SetGpuProfilingEndPoint //! @sa GetGpuProfilingTotalCostTime s32 AddGpuProfilingStartPoint(bool IsInTotal); //! @brief GPU プロファイルエントリの終点を設定します。 //! //! 指定した GPU プロファイルエントリの終点を //! この関数が実行された時点で最後に蓄積されたコマンドリクエストの終了時に設定します。 //! 計測された実行時間を取得するには GetGpuProfilingCostTime() や GetGpuProfilingTotalCostTime() を使用します。 //! //! この関数は 3D コマンドバッファを区切らないので、必要に応じて nngxSplitCmdlist() 関数を呼び出してください。 //! //! 複数の CommandListSwapper インスタンスから GPU プロファイルを行うことはできません。 //! //! @param profilingId AddGpuProfilerStartPoint() で返されたエントリの番号を指定します。 //! //! @sa AddGpuProfilingStartPoint //! @sa GetGpuProfilingTotalCostTime void SetGpuProfilingEndPoint(u32 profilingId); //! @brief 計測された GPU プロファイルエントリの実行時間を取得します。 //! //! 実行されたコマンドリストに追加された GPU プロファイルエントリの実行時間をミリ秒単位で取得します。 //! この関数で実行時間を取得する前に、WaitDone() によりコマンドリストの終了待ちをする必要があります。 //! 指定した番号のエントリが存在しない場合、この関数は 0.0f を返します。 //! //! コマンドリストが多重化されている場合は Swap() 実行時に、 //! そうでない場合は Run() 実行時に GPU プロファイルの結果が失われます。 //! //! 得られる GPU プロファイルエントリの結果はバインドされているコマンドリストではなく、 //! WaitDone() で終了待ちをしたコマンドリストが対象であることに注意してください。 //! //! @param profilingId AddGpuProfilingStartPoint() で返されたエントリの番号を指定します。 //! //! @return ミリ秒単位の実行時間です。 //! //! @sa AddGpuProfilingStartPoint //! @sa GetGpuProfilingTotalCostTime f32 GetGpuProfilingCostTime(u32 profilingId); //! @brief GPU プロファイルエントリの合計実行時間を取得します。 //! //! AddGpuProfilerStartPoint() で、引数 IsInTotal に true を指定した GPU プロファイルエントリの合計実行時間をミリ秒単位で取得します。 //! 実行区間が重複している GPU プロファイルエントリについても単純に加算されますので注意してください。 //! //! コマンドリストが多重化されている場合は Swap() 実行時に、 //! そうでない場合は Run() 実行時に GPU プロファイルの結果が失われます。 //! //! 得られる GPU プロファイルエントリの結果はバインドされているコマンドリストではなく、 //! WaitDone() で終了待ちをしたコマンドリストが対象であることに注意してください。 //! //! @return ミリ秒単位の実行時間です。 //! //! @sa AddGpuProfilingStartPoint //! @sa GetGpuProfilingCostTime f32 GetGpuProfilingTotalCostTime(); //} //---------------------------------------- //! @name 取得/設定 //@{ //! @brief コマンドリストの ID を取得します。 GLuint GetCommandListId() const { return m_CommandLists[m_BoundIndex]; } //! @brief コマンドリストの数を取得します。 size_t GetListCount() const { return this->m_CommandLists.size(); } //! @brief 蓄積された 3D コマンドバッファのサイズを取得します。 //! //! 現在バインドされているコマンドリストの 3D コマンドバッファのサイズを //! バイト単位で取得します。 //! //! 再利用するために保存されたコマンドリストの 3D コマンドバッファのサイズを求めるときは //! GetReusableCommandBufferSize を使用してください。 //! //! @return 3D コマンドバッファのサイズをバイト単位で返します。 //! //! @sa GetReusableCommandBufferSize int GetCommandBufferSize() const; //! @brief 再利用するために保存されたコマンドリストの 3D コマンドバッファのサイズを取得します。 //! //! 再利用するために保存されたコマンドリストの 3D コマンドバッファのサイズを //! バイト単位で取得します。 //! //! 現在バインドされているコマンドリストの 3D コマンドバッファのサイズを求めるときは //! GetCommandBufferSize を使用してください。 //! //! また、StartCommandSave と EndCommandSave の間で再利用するコマンドのサイズを取得するときは、 //! GetCommandBufferSize を使用してください。StartCommandSave で再利用するためのコマンドリストがバインドされるためです。 //! //! @return 3D コマンドバッファのサイズをバイト単位で返します。 //! //! @sa GetCommandBufferSize //! @sa StartCommandSave int GetReusableCommandBufferSize() const; //@} //---------------------------------------- //! @name コマンドの再利用 //@{ //! @brief 再利用するコマンドの保存を開始します。 //! //! 再利用するためのコマンドリストをバインドし、コマンドの保存を開始します。 //! 保存は EndSaving() が実行されるまで行われます。 //! 保存されたコマンドは ReuseCommand() で再利用することができます。 //! //! コマンドの再利用を有効にするためには Create() の引数である Description 構造体の //! メンバ reusableListBufferSize と reusableListRequestCount に正の値を設定します。 //! //! @sa EndCommandSave //! @sa ReuseCommand void StartCommandSave(); //! @brief 再利用するコマンドの保存を終了します。 //! //! コマンドの保存を終了し、コマンドリストをバインドしなおします。 //! //! @sa StartCommandSave //! @sa ReuseCommand void EndCommandSave(); //! @brief 保存されたコマンドを再利用します。 //! //! StartCommandSave() と EndCommandSave() により保存されたコマンドをバインドされているコマンドリストへ追加します。 //! isCopyBuffer に true を指定した場合はコマンドがコピーされて追加されます。 //! false を指定した場合は、3D コマンドバッファは保存されたコマンドを参照します。 //! 詳細は CTR-SDK の nngxUseSavedCmdlist 関数を参照してください。 //! //! @param[in] isCopyBuffer バッファをコピーするかを指定します。 //! //! @sa StartCommandSave //! @sa EndCommandSave void ReuseCommand(bool isCopyBuffer); //@} private: CommandListSwapper(os::IAllocator* allocator, Description& description); ~CommandListSwapper() {} //! @brief GPU プロファイルエントリの実行時間を計算します。 void CalcGpuProfilingCostTime(); //! @brief コマンドリストの実行時間を計測するためにシステムチックを記録します。 void SetGpuProfilingTick(GLint id); //! @brief 登録されるコールバック関数です。 static void CommandListCallback(GLint id); //! @brief コールバックを登録します。 //! //! @return コールバックが登録されたコマンドリクエストの番号を返します。 GLuint RegisterCallback(); //! @brief コマンドリスト実行完了待ちがタイムアウトした際に呼び出されるコールバック関数です。 static void TimeoutWaitCommandListDone(); //! @brief コマンドリストのパラメータをログに出力します。 void DumpCommandListParameter(); struct GpuProfilingEntry { GLuint beginId; GLuint endId; s64 beginTick; s64 endTick; f32 costTime; bool isInTotal; GpuProfilingEntry() : beginId(0), endId(0), beginTick(0), endTick(0), costTime(0.0f), isInTotal(false) {} }; os::IAllocator* m_Allocator; typedef ut::MoveArray CommandListArray; CommandListArray m_CommandLists; int m_BoundIndex; int m_RunningIndex; bool m_IsRunning; typedef ut::MoveArray GpuProfilingEntryArray; GpuProfilingEntryArray m_GpuProfilingEntries; GpuProfilingEntryArray m_GpuProfilingResults; CommandListArray m_ReusableCommandLists; GLuint m_ReusableBufferOffset; GLsizei m_ReusableBufferSize; GLuint m_ReusableRequestId; GLsizei m_ReusableRequestSize; u8* m_DumpCommandListBuffer; static const s64 COMMAND_LIST_WAIT_TIME_OUT; static CommandListSwapper* s_CommandListSwapper; }; } // namespace demo } // namespace nw #endif // NW_DEMO_COMMANDLISTSWAPPER_H_