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