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