1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: gfx_DisplayList.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: 26419 $ 14 *---------------------------------------------------------------------------*/ 15 #ifndef NW_GFX_DISPLAYLIST_H_ 16 #define NW_GFX_DISPLAYLIST_H_ 17 18 #include <nw/types.h> 19 #include <nw/ut/ut_Inlines.h> 20 #include <nw/gfx/gfx_GlImplement.h> 21 #include <nw/dev.h> 22 23 #include <gles2/gl2.h> 24 #include <gles2/gl2ext.h> 25 #include <nn/gx.h> 26 #include <cstring> 27 28 namespace nw { 29 namespace gfx { 30 namespace internal { 31 32 33 //-------------------------------------------------------------------------- 34 //! @brief プリミティブなコマンド列を生成する為のユーティリティです。 35 //--------------------------------------------------------------------------- 36 class GpuCommand 37 { 38 public: 39 40 //-------------------------------------------------------------------------- 41 //! @brief コンストラクタです。 42 //-------------------------------------------------------------------------- GpuCommand()43 GpuCommand() 44 : m_CurrentBuffer( NULL ), 45 m_StartAddress( NULL ), 46 m_CurrentHeader( NULL ), 47 m_Size(0) 48 {} 49 50 //-------------------------------------------------------------------------- 51 //! @brief コマンドの生成を開始します。 52 //! 53 //! @param[out] addr コマンドを構築する先頭アドレスです。 54 //-------------------------------------------------------------------------- Begin(void * addr)55 void Begin(void* addr) 56 { 57 NW_NULL_ASSERT( addr ); 58 59 m_CurrentBuffer = reinterpret_cast<u32*>(addr); 60 m_StartAddress = reinterpret_cast<u32*>(addr); 61 } 62 63 //-------------------------------------------------------------------------- 64 //! @brief ひとまとまりのコマンド生成を開始します。単一アドレスへの書き込みです。 65 //! 66 //! @param[in] regAddr 書き込み先のレジスタアドレスです。 67 //! @param[in] byteEnable バイトイネーブルの設定です。 68 //-------------------------------------------------------------------------- 69 void WriteHeader(u32 regAddr, u8 byteEnable = 0xf) 70 { 71 this->Align8(); 72 73 m_CurrentHeader = m_CurrentBuffer + 1; 74 *m_CurrentHeader = internal::MakeCommandHeader(regAddr, 1, false, byteEnable); 75 } 76 77 //-------------------------------------------------------------------------- 78 //! @brief ひとまとまりのコマンド生成を開始します。連続アドレスへの書き込みです。 79 //! 80 //! @param[in] regAddr 書き込み先のレジスタアドレスです。 81 //! @param[in] byteEnable バイトイネーブルの設定です。 82 //-------------------------------------------------------------------------- 83 void WriteHeaderIncremental(u32 regAddr, u8 byteEnable = 0xf) 84 { 85 this->Align8(); 86 87 m_CurrentHeader = m_CurrentBuffer + 1; 88 *m_CurrentHeader = internal::MakeCommandHeader(regAddr, 1, true, byteEnable); 89 } 90 91 //-------------------------------------------------------------------------- 92 //! @brief u32フォーマットのデータを書き込みます。 93 //! 94 //! @param[in] data 書き込むデータです。 95 //-------------------------------------------------------------------------- WriteData(u32 data)96 void WriteData(u32 data) 97 { 98 *m_CurrentBuffer = data; 99 100 if (m_Size == 0) 101 { 102 m_Size = 2; 103 m_CurrentBuffer += 2; 104 } 105 else 106 { 107 m_Size += 1; 108 m_CurrentBuffer += 1; 109 } 110 } 111 112 //-------------------------------------------------------------------------- 113 //! @brief データ列を書き込みます。 114 //! 115 //! @param[in] data データ列へのポインタです。 116 //! @param[in] count 格納するデータ数です。 117 //-------------------------------------------------------------------------- WriteData(const void * data,int count)118 void WriteData(const void* data, int count) 119 { 120 NW_NULL_ASSERT( data ); 121 NW_ASSERT( count > 0 ); 122 123 const u32* pData = reinterpret_cast<const u32*>(data); 124 int copyCount = count; 125 126 if (m_Size == 0) 127 { 128 *m_CurrentBuffer = *pData; 129 pData += 1; 130 copyCount -= 1; 131 m_CurrentBuffer += 2; 132 m_Size = 2; 133 } 134 135 if (copyCount > 0) 136 { 137 nw::os::MemCpy(m_CurrentBuffer, pData, copyCount * sizeof(u32)); 138 m_Size += copyCount; 139 m_CurrentBuffer += copyCount; 140 } 141 } 142 143 //-------------------------------------------------------------------------- 144 //! @brief コマンドを生成を終了します。 145 //! 146 //! @return 先頭アドレスからのデータサイズを返します。 147 //-------------------------------------------------------------------------- End()148 u32 End() 149 { 150 this->Align8(); 151 152 return reinterpret_cast<u32>(m_CurrentBuffer) - reinterpret_cast<u32>(m_StartAddress); 153 } 154 155 private: 156 157 //-------------------------------------------------------------------------- 158 //! @brief コマンド終端の64bitアライメントを挿入します。 159 //-------------------------------------------------------------------------- Align8()160 void Align8() 161 { 162 enum 163 { 164 SIZE_SHIFT = 20, 165 SIZE_WIDTH = 8 166 }; 167 168 // ヘッダにデータ数を保存。 169 if (m_Size > 0) 170 { 171 NW_NULL_ASSERT( m_CurrentHeader ); 172 173 // データ数は、ヘッダを除いて m_Size - 1。レジスタへは count - 1 を格納するので -2。 174 *m_CurrentHeader |= ut::internal::MakeBits(m_Size - 2, SIZE_WIDTH, SIZE_SHIFT); 175 m_CurrentHeader = NULL; 176 } 177 178 // アライメントの挿入。 179 if ((m_Size % 2) == 1) 180 { 181 *m_CurrentBuffer = 0x0; 182 m_CurrentBuffer += 1; 183 } 184 185 m_Size = 0; 186 } 187 188 u32* m_CurrentBuffer; 189 u32* m_StartAddress; 190 u32* m_CurrentHeader; 191 u32 m_Size; 192 }; 193 194 195 } // namespace internal 196 } // namespace gfx 197 } // namespace nw 198 199 #endif // NW_GFX_DISPLAYLIST_H_ 200