1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: gr_Vertex.h 4 5 Copyright (C)2010 Nintendo Co., Ltd. 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 $Rev: 33699 $ 14 *---------------------------------------------------------------------------*/ 15 16 #ifndef NN_GR_VERTEX_H_ 17 #define NN_GR_VERTEX_H_ 18 19 #include <nn/gr/CTR/gr_Prefix.h> 20 #include <nn/gr/CTR/gr_BindSymbol.h> 21 22 namespace nn 23 { 24 namespace gr 25 { 26 namespace CTR 27 { 28 29 /*! 30 @brief 頂点バッファオブジェクト関連の設定のためのクラスです。 31 */ 32 class Vertex 33 { 34 public : 35 //! 頂点属性の最大数は12です(v0,v1,...,v11)。 36 static const u32 VERTEX_ATTRIBUTE_MAX = 12; 37 38 //! 頂点属性の要素数の最大数は4です(x,y,z,w)。 39 static const u32 VERTEX_ATTRIBUTE_DIMENSION_MAX = 4; 40 41 //! 頂点有効化のコマンド最大数です。 42 static const u32 VERTEX_ENABLE_COMMAND_MAX = 12 + VERTEX_ATTRIBUTE_MAX * 6; 43 44 /*! 45 @brief インターリーブ情報を設定するためのクラスです。 46 */ 47 class InterleaveInfo 48 { 49 public: 50 /*! 51 @brief データ数です。 52 */ 53 u8 dataNum; 54 NN_PADDING3; 55 56 /*! 57 @brief 頂点データの型の配列です。 58 型は @ref PicaDataVertexAttrType です。 59 */ 60 PicaDataVertexAttrType dataType[ VERTEX_ATTRIBUTE_MAX ]; 61 62 /*! 63 @brief 頂点シェーダの入力のシンボルの配列です。 64 型は nn::gr::CTR::BindSymbolVSInput[] です。 65 */ 66 const nn::gr::CTR::BindSymbolVSInput* symbol[ VERTEX_ATTRIBUTE_MAX ]; 67 InterleaveInfo()68 InterleaveInfo() { std::memset( this, 0, sizeof( InterleaveInfo ) ); } 69 }; 70 71 public : 72 /*! 73 @brief 頂点インデックスのストリーム設定のためのクラスです。 74 */ 75 class IndexStream 76 { 77 public : 78 /*! 79 @brief 頂点ストリームの物理アドレスの設定です。型は uptr です。 80 */ 81 uptr physicalAddr; 82 83 /*! 84 @brief 描画頂点数の設定です。型は u32 です。 85 */ 86 u32 drawVtxNum; 87 88 /*! 89 @brief インデックスの要素がGLubyteの場合、 true を設定します。型は bool です。 90 */ 91 bool isUnsignedByte; 92 NN_PADDING3; 93 }; 94 95 public: // 頂点属性の設定 96 /*! 97 @brief 頂点配列を設定します。DMPGLにおける glEnableVertexAttribArray() に対応します。 98 99 @param[in] symbol 頂点シェーダの入力のシンボルです。 100 @param[in] physical_addr 頂点配列の物理アドレスを指定します。 101 @param[in] type 各要素の型、および、要素数をもとに配列の型を指定します。 102 */ 103 void EnableAttrAsArray( const nn::gr::CTR::BindSymbolVSInput& symbol, const uptr physical_addr, const PicaDataVertexAttrType type ); 104 105 /*! 106 @brief 固定頂点を設定します。DMPGLにおける glVertexAttrib[N]fv()に対応します。 107 バインドする入力レジスタは、ShaderクラスのSearchBindSymbol()で調べることが出来ます。 108 109 @param[in] symbol 頂点シェーダの入力のシンボルです。 110 @param[in] dimension 要素の数を指定します。 111 @param[in] param 固定頂点パラメータを指定します。param[0],[1],[2],[3]が、それぞれ、x,y,z,wに対応します。 112 113 @see Shader::SearchBindSymbol() 114 */ 115 void EnableAttrAsConst( const nn::gr::CTR::BindSymbolVSInput& symbol, const u8 dimension, const f32 param[] ); 116 117 /*! 118 @brief インターリーブアレイを設定します。 119 120 @param[in] interleave_info インターリーブ情報の構造体です。 121 @param[in] physical_addr 物理アドレスを設定します。 122 */ 123 void EnableInterleavedArray( const nn::gr::CTR::Vertex::InterleaveInfo& interleave_info, const uptr physical_addr ); 124 125 public : // 設定からコマンドを生成する 126 /*! 127 @brief 設定された情報をもとに、頂点属性の有効化コマンドを生成します。 128 129 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 130 131 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 132 */ 133 MakeEnableAttrCommand(bit32 * command)134 bit32* MakeEnableAttrCommand( bit32* command ) const 135 { 136 if ( m_CmdCacheVertexNum == 0 ) 137 { 138 // キャッシュの生成 139 m_CmdCacheVertexNum = MakeEnableAttrCommand_( m_CmdCacheVertex ) - m_CmdCacheVertex; 140 } 141 142 std::memcpy( command, m_CmdCacheVertex, m_CmdCacheVertexNum * sizeof( bit32 ) ); 143 return command + m_CmdCacheVertexNum; 144 } 145 146 /*! 147 @brief 設定された情報をもとに、描画コマンドを生成します。 148 149 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 150 @param[in] index_stream インデックスのストリームです。 151 152 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 153 */ 154 bit32* MakeDrawCommand( bit32* command, const IndexStream& index_stream ) const; 155 156 /*! 157 @brief 有効な頂点属性を無効化するコマンドを生成します。 158 159 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 160 161 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 162 */ MakeDisableAttrCommand(bit32 * command)163 bit32* MakeDisableAttrCommand( bit32* command ) const 164 { 165 for ( int index = 0; index < VERTEX_ATTRIBUTE_MAX; ++index ) 166 { 167 // 有効なロードアレイを無効化するコマンドの生成 168 if ( m_LoadArray[ index ].IsEnable() ) 169 { 170 // 0x203 + 3N, ロードアレイのアドレスオフセットを無効化するコマンドの生成 171 *command++ = 0; 172 *command++ = 173 PICA_CMD_HEADER_BURSTSEQ( PICA_REG_LOAD_ARRAY0_ATTR_OFFSET + 3 * index, 0x3 ); 174 // 0x204 + 3N, ロードアレイの 0-7 番目の要素を無効化するコマンドの生成 175 *command++ = 0; 176 // 0x205 + 3N [15: 0]ロードアレイの 8-11 番目の要素を無効化するコマンドの生成 177 // [23:16] ロードアレイの 1頂点のバイト数を無効化するコマンドの生成 178 // [31:28] ロードアレイの 要素数を無効化するコマンドの生成 179 *command++ = 0; 180 } 181 else 182 { 183 *command++ = 0; 184 // 0x205 + 3N [23:16] ロードアレイの 1頂点のバイト数を無効化するコマンドの生成 185 // [31:28] ロードアレイの 要素数を無効化するコマンドの生成 186 *command++ = 187 PICA_CMD_HEADER_SINGLE( PICA_REG_LOAD_ARRAY0_ELEMENT1 + 3 * index ); 188 } 189 190 // 有効な固定頂点属性を無効化するコマンドの生成 191 if ( m_AttrConst[ index ].IsEnable() ) 192 { 193 *command++ = index; 194 *command++ = PICA_CMD_HEADER_BURSTSEQ( PICA_REG_VS_FIXED_ATTR, 4 ); 195 *command++ = 0; 196 *command++ = 0; 197 *command++ = 0; 198 // padding 199 *command++ = 0; 200 } 201 } 202 203 return command; 204 } 205 206 /*! 207 @brief 頂点属性の無効化するコマンドを全て生成します。 208 209 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 210 211 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 212 */ MakeDisableCommand(bit32 * command)213 static bit32* MakeDisableCommand( bit32* command ) 214 { 215 *command++ = 0; 216 *command++ = PICA_CMD_HEADER_SINGLE( 0x201 ); 217 218 *command++ = 0; 219 *command++ = PICA_CMD_HEADER_SINGLE( 0x202 ); 220 221 // 0x203 + 3N, 0x204 + 3N, 0x205 + 3N (N = 0-11) を全て無効化するコマンドの生成 222 const int size = ( 2 + 3 * VERTEX_ATTRIBUTE_MAX ) * sizeof( bit32 ); 223 std::memset( command, 0, size ); 224 command[ 1 ] = PICA_CMD_HEADER_BURSTSEQ( PICA_REG_LOAD_ARRAY0_ATTR_OFFSET, VERTEX_ATTRIBUTE_MAX * 3 ); 225 command += size / sizeof( bit32 ); 226 227 for ( int i = 0; i < VERTEX_ATTRIBUTE_MAX; ++i ) 228 { 229 // 0x232 230 *command++ = i; 231 *command++ = PICA_CMD_HEADER_BURSTSEQ( PICA_REG_VS_FIXED_ATTR, 4 ); 232 233 // 0x233 234 *command++ = 0; 235 // 0x234 236 *command++ = 0; 237 238 // 0x235 239 *command++ = 0; 240 // padding 241 *command++ = 0; 242 } 243 244 return command; 245 } 246 247 public : // 無効化 248 249 /*! 250 @brief 頂点属性の無効化をおこないます。DMPGLにおけるglDisableVertexAttrib()に対応します。 251 252 @param[in] symbol 無効化する入力シンボルを指定します。 253 */ DisableAttr(const nn::gr::CTR::BindSymbolVSInput & symbol)254 void DisableAttr( const nn::gr::CTR::BindSymbolVSInput& symbol ) 255 { 256 DisableAttr_( symbol.start ); 257 } 258 259 /*! 260 @brief すべての頂点属性の無効化をおこないます。 261 */ DisableAll()262 void DisableAll() 263 { 264 std::memset( this, 0, sizeof( Vertex ) ); 265 } 266 267 public : 268 /*! 269 コンストラクタでは、すべての頂点属性が無効になった状態に初期化されます。 270 */ Vertex()271 explicit Vertex() 272 { 273 std::memset( this, 0, sizeof( Vertex ) ); 274 } 275 276 protected : 277 /*! 278 @brief 頂点配列設定のためのクラスです。 279 */ 280 struct LoadArray 281 { 282 public : 283 284 /*! 285 @brief 頂点配列の物理アドレスの設定です。型は uptr です。 286 */ 287 uptr physicalAddr; 288 289 /*! 290 @brief 頂点配列の型の設定する配列です。 291 型は @ref PicaDataVertexAttrType[] です。 292 */ 293 PicaDataVertexAttrType type[ VERTEX_ATTRIBUTE_MAX ]; 294 295 /*! 296 @brief 属性のサイズを指定する配列です。 297 型は u32[] です。 298 配列のサイズは nn::gr::CTR::Vertex::VERTEX_ATTRIBUTE_MAX です。 299 */ 300 u32 byte[ VERTEX_ATTRIBUTE_MAX ]; 301 302 /*! 303 @brief 関連付けられているレジスタを指定します。 304 型は int[] です。 305 配列のサイズは nn::gr::CTR::Vertex::VERTEX_ATTRIBUTE_MAX です。 306 */ 307 int bind[ VERTEX_ATTRIBUTE_MAX ]; 308 309 /*! 310 @brief 有効化されているかどうかを返します。 311 312 @return 有効なときに true、そうでないときに false を返します。 313 */ IsEnableLoadArray314 bool IsEnable() const { return physicalAddr != 0; } 315 316 /*! 317 @brief 無効化します。 318 */ 319 void CheckDisable(); 320 }; 321 322 /*! 323 @brief 固定頂点属性の設定のためのクラスです。 324 */ 325 class AttrConst 326 { 327 public : 328 329 /*! 330 @brief 固定頂点属性の要素数の設定です(1から4)。 331 型は u8 です。 332 */ 333 u8 dimension; 334 NN_PADDING3; 335 336 /*! 337 @brief 固定頂点属性の固定値の設定です。 338 配列のサイズは nn::gr::CTR::Vertex::VERTEX_ATTRIBUTE_DIMENSION_MAX です。 339 */ 340 f32 param[ VERTEX_ATTRIBUTE_DIMENSION_MAX ]; 341 342 /*! 343 @brief 有効化されているかどうかを返します。 344 */ IsEnable()345 bool IsEnable() const { return dimension != 0; } 346 347 /*! 348 @brief 無効化します。 349 */ Disable()350 void Disable() { dimension = 0; } 351 }; 352 353 protected : 354 /*! 355 @brief 属性を無効化します。 356 357 @param[in] bind_reg バインドするレジスタを指定します。 358 */ 359 void DisableAttr_( const bit32 bind_reg ); 360 361 /*! 362 @brief 属性を有効化するコマンドを生成します。 363 364 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 365 366 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 367 */ 368 bit32* MakeEnableAttrCommand_( bit32* command ) const; 369 370 protected : 371 mutable u32 m_CmdCacheVertexNum; 372 mutable bit32 m_CmdCacheVertex[ VERTEX_ENABLE_COMMAND_MAX ]; 373 374 bool m_IsEnableReg[ VERTEX_ATTRIBUTE_MAX ]; 375 376 LoadArray m_LoadArray[ VERTEX_ATTRIBUTE_MAX ]; 377 AttrConst m_AttrConst[ VERTEX_ATTRIBUTE_MAX ]; 378 }; 379 380 } // namespace CTR 381 } // namespace gr 382 } // namespace nn 383 384 385 #endif // NN_GR_VERTEX_H_ 386