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: 29329 $
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                 /*
104                   バインドする入力レジスタは、Shader クラスの SearchBindSymbol() で調べることが出来ます。
105                   typeには,
106                   PICA_DATA_SIZE_1_BYTE、
107                   PICA_DATA_SIZE_1_UNSIGNED_BYTE、
108                   PICA_DATA_SIZE_1_SHORT、
109                   PICA_DATA_SIZE_1_FLOAT、
110                   PICA_DATA_SIZE_2_BYTE、
111                   PICA_DATA_SIZE_2_UNSIGNED_BYTE、
112                   PICA_DATA_SIZE_2_SHORT、
113                   PICA_DATA_SIZE_2_FLOAT、
114                   PICA_DATA_SIZE_3_BYTE、
115                   PICA_DATA_SIZE_3_UNSIGNED_BYTE、
116                   PICA_DATA_SIZE_3_SHORT、
117                   PICA_DATA_SIZE_3_FLOAT、
118                   PICA_DATA_SIZE_4_BYTE、
119                   PICA_DATA_SIZE_4_UNSIGNED_BYTE、
120                   PICA_DATA_SIZE_4_SHORT、
121                   PICA_DATA_SIZE_4_FLOAT
122                   のいずれかを設定します。
123                  */
124                 void EnableAttrAsArray( const nn::gr::CTR::BindSymbolVSInput& symbol, const uptr physical_addr, const PicaDataVertexAttrType type );
125 
126                 /*!
127                     @brief 固定頂点を設定します。DMPGLにおける glVertexAttrib[N]fv()に対応します。
128                            バインドする入力レジスタは、ShaderクラスのSearchBindSymbol()で調べることが出来ます。
129 
130                     @param[in] symbol        頂点シェーダの入力のシンボルです。
131                     @param[in] dimension     要素の数を指定します。
132                     @param[in] param       固定頂点パラメータを指定します。param[0],[1],[2],[3]が、それぞれ、x,y,z,wに対応します。
133 
134                     @see       Shader::SearchBindSymbol()
135                 */
136                 void EnableAttrAsConst( const nn::gr::CTR::BindSymbolVSInput& symbol, const u8 dimension, const f32 param[] );
137 
138                 /*!
139                     @brief インターリーブアレイを設定します。
140 
141                     @param[in] interleave_info インターリーブ情報の構造体です。
142                     @param[in] physical_addr   物理アドレスを設定します。
143                 */
144                 void EnableInterleavedArray( const nn::gr::CTR::Vertex::InterleaveInfo& interleave_info, const uptr physical_addr );
145 
146             public : // 設定からコマンドを生成する
147                 /*!
148                     @brief 設定された情報をもとに、頂点属性の有効化コマンドを生成します。
149 
150                     @param[in] command 描画コマンドの書き込み先の先頭アドレスです。
151 
152                     @return    書き込まれた描画コマンドの終端の次のアドレスを返します。
153                  */
154 
MakeEnableAttrCommand(bit32 * command)155                 bit32* MakeEnableAttrCommand( bit32* command ) const
156                 {
157                     if ( m_CmdCacheVertexNum == 0 )
158                     {
159                         // キャッシュの生成
160                         m_CmdCacheVertexNum = MakeEnableAttrCommand_( m_CmdCacheVertex ) - m_CmdCacheVertex;
161                     }
162 
163                     std::memcpy( command, m_CmdCacheVertex, m_CmdCacheVertexNum * sizeof( bit32 ) );
164                     return command + m_CmdCacheVertexNum;
165                 }
166 
167                 /*!
168                     @brief 設定された情報をもとに、描画コマンドを生成します。
169 
170                     @param[in] command 描画コマンドの書き込み先の先頭アドレスです。
171                     @param[in] index_stream インデックスのストリームです。
172 
173                     @return    書き込まれた描画コマンドの終端の次のアドレスを返します。
174                  */
175                 bit32* MakeDrawCommand( bit32* command, const IndexStream& index_stream ) const;
176 
177                 /*!
178                     @brief     有効な頂点属性を無効化するコマンドを生成します。
179 
180                     @param[in] command 描画コマンドの書き込み先の先頭アドレスです。
181 
182                     @return    書き込まれた描画コマンドの終端の次のアドレスを返します。
183                  */
MakeDisableAttrCommand(bit32 * command)184                 bit32* MakeDisableAttrCommand( bit32* command ) const
185                 {
186                     for ( int index = 0; index < VERTEX_ATTRIBUTE_MAX; ++index )
187                     {
188                         // 有効なロードアレイを無効化するコマンドの生成
189                         if ( m_LoadArray[ index ].IsEnable() )
190                         {
191                             // 0x203 + 3N, ロードアレイのアドレスオフセットを無効化するコマンドの生成
192                             *command++ = 0;
193                             *command++ =
194                                 PICA_CMD_HEADER_BURSTSEQ( PICA_REG_LOAD_ARRAY0_ATTR_OFFSET + 3 * index, 0x3 );
195                             // 0x204 + 3N, ロードアレイの 0-7 番目の要素を無効化するコマンドの生成
196                             *command++ = 0;
197                             // 0x205 + 3N [15: 0]ロードアレイの 8-11 番目の要素を無効化するコマンドの生成
198                             //            [23:16] ロードアレイの 1頂点のバイト数を無効化するコマンドの生成
199                             //            [31:28] ロードアレイの 要素数を無効化するコマンドの生成
200                             *command++ = 0;
201                         }
202                         else
203                         {
204                             *command++ = 0;
205                             // 0x205 + 3N [23:16] ロードアレイの 1頂点のバイト数を無効化するコマンドの生成
206                             //            [31:28] ロードアレイの 要素数を無効化するコマンドの生成
207                             *command++ =
208                                 PICA_CMD_HEADER_SINGLE( PICA_REG_LOAD_ARRAY0_ELEMENT1 + 3 * index );
209                         }
210 
211                         // 有効な固定頂点属性を無効化するコマンドの生成
212                         if ( m_AttrConst[ index ].IsEnable() )
213                         {
214                             *command++ = index;
215                             *command++ = PICA_CMD_HEADER_BURSTSEQ( PICA_REG_VS_FIXED_ATTR, 4 );
216                             *command++ = 0;
217                             *command++ = 0;
218                             *command++ = 0;
219                             // padding
220                             *command++ = 0;
221                         }
222                     }
223 
224                     return command;
225                 }
226 
227                 /*!
228                     @brief 頂点属性の無効化するコマンドを全て生成します。
229 
230                     @param[in] command 描画コマンドの書き込み先の先頭アドレスです。
231 
232                     @return    書き込まれた描画コマンドの終端の次のアドレスを返します。
233                  */
MakeDisableCommand(bit32 * command)234                 static bit32* MakeDisableCommand( bit32* command )
235                 {
236                     *command++ = 0;
237                     *command++ = PICA_CMD_HEADER_SINGLE( 0x201 );
238 
239                     *command++ = 0;
240                     *command++ = PICA_CMD_HEADER_SINGLE( 0x202 );
241 
242                     // 0x203 + 3N, 0x204 + 3N, 0x205 + 3N (N = 0-11) を全て無効化するコマンドの生成
243                     const int size = ( 2 + 3 * VERTEX_ATTRIBUTE_MAX ) * sizeof( bit32 );
244                     std::memset( command, 0, size );
245                     command[ 1 ] = PICA_CMD_HEADER_BURSTSEQ( PICA_REG_LOAD_ARRAY0_ATTR_OFFSET, VERTEX_ATTRIBUTE_MAX * 3 );
246                     command += size / sizeof( bit32 );
247 
248                     for ( int i = 0; i < VERTEX_ATTRIBUTE_MAX; ++i )
249                     {
250                         // 0x232
251                         *command++ = i;
252                         *command++ = PICA_CMD_HEADER_BURSTSEQ( PICA_REG_VS_FIXED_ATTR, 4 );
253 
254                         // 0x233
255                         *command++ = 0;
256                         // 0x234
257                         *command++ = 0;
258 
259                         // 0x235
260                         *command++ = 0;
261                         // padding
262                         *command++ = 0;
263                     }
264 
265                     return command;
266                 }
267 
268             public : // 無効化
269 
270                 /*!
271                     @brief 頂点属性の無効化をおこないます。DMPGLにおけるglDisableVertexAttrib()に対応します。
272 
273                     @param[in] symbol      無効化する入力シンボルを指定します。
274                  */
DisableAttr(const nn::gr::CTR::BindSymbolVSInput & symbol)275                 void DisableAttr( const nn::gr::CTR::BindSymbolVSInput& symbol )
276                 {
277                     DisableAttr_( symbol.start );
278                 }
279 
280                 /*!
281                     @brief すべての頂点属性の無効化をおこないます。
282                  */
DisableAll()283                 void DisableAll()
284                 {
285                     std::memset( this, 0, sizeof( Vertex ) );
286                 }
287 
288             public :
289                 /*!
290                     コンストラクタでは、すべての頂点属性が無効になった状態に初期化されます。
291                  */
Vertex()292                 explicit Vertex()
293                 {
294                     std::memset( this, 0, sizeof( Vertex ) );
295                 }
296 
297             private :
298                 /*!
299                     @brief 頂点配列設定のためのクラスです。
300                  */
301                 struct LoadArray
302                 {
303                 public :
304 
305                     /*!
306                         @brief 頂点配列の物理アドレスの設定です。型は uptr です。
307                     */
308                     uptr physicalAddr;
309 
310                     /*!
311                         @brief 頂点配列の型の設定する配列です。
312                                型は @ref PicaDataVertexAttrType[] です。
313                     */
314                     /*
315                         PICA_DATA_SIZE_1_BYTE
316                         PICA_DATA_SIZE_1_UNSIGNED_BYTE
317                         PICA_DATA_SIZE_1_SHORT
318                         PICA_DATA_SIZE_1_FLOAT
319                         PICA_DATA_SIZE_2_BYTE
320                         PICA_DATA_SIZE_2_UNSIGNED_BYTE
321                         PICA_DATA_SIZE_2_SHORT
322                         PICA_DATA_SIZE_2_FLOAT
323                         PICA_DATA_SIZE_3_BYTE
324                         PICA_DATA_SIZE_3_UNSIGNED_BYTE
325                         PICA_DATA_SIZE_3_SHORT
326                         PICA_DATA_SIZE_3_FLOAT
327                         PICA_DATA_SIZE_4_BYTE
328                         PICA_DATA_SIZE_4_UNSIGNED_BYTE
329                         PICA_DATA_SIZE_4_SHORT
330                         PICA_DATA_SIZE_4_FLOAT
331                         のいずれかを設定します。
332                     */
333                     PicaDataVertexAttrType type[ VERTEX_ATTRIBUTE_MAX ];
334 
335                     /*!
336                         @brief 属性のサイズを指定する配列です。
337                                型は u32[] です。
338                                配列のサイズは nn::gr::CTR::Vertex::VERTEX_ATTRIBUTE_MAX です。
339                     */
340                     u32 byte[ VERTEX_ATTRIBUTE_MAX ];
341 
342                     /*!
343                         @brief 関連付けられているレジスタを指定します。
344                                型は int[] です。
345                                配列のサイズは nn::gr::CTR::Vertex::VERTEX_ATTRIBUTE_MAX です。
346                     */
347                     int bind[ VERTEX_ATTRIBUTE_MAX ];
348 
349                     /*!
350                         @brief 有効化されているかどうかを返します。
351 
352                         @return 有効なときに true、そうでないときに false を返します。
353                     */
IsEnableLoadArray354                     bool IsEnable() const { return physicalAddr != 0; }
355 
356                     /*!
357                         @brief 無効化します。
358                     */
359                     void CheckDisable();
360                 };
361 
362                 /*!
363                     @brief 固定頂点属性の設定のためのクラスです。
364                  */
365                 class AttrConst
366                 {
367                 public :
368 
369                     /*!
370                         @brief 固定頂点属性の要素数の設定です(1から4)。
371                                型は u8 です。
372                     */
373                     u8 dimension;
374                     NN_PADDING3;
375 
376                     /*!
377                         @brief 固定頂点属性の固定値の設定です。
378                                配列のサイズは nn::gr::CTR::Vertex::VERTEX_ATTRIBUTE_DIMENSION_MAX です。
379                     */
380                     f32 param[ VERTEX_ATTRIBUTE_DIMENSION_MAX ];
381 
382                     /*!
383                         @brief 有効化されているかどうかを返します。
384                     */
IsEnable()385                     bool IsEnable() const { return dimension != 0; }
386 
387                     /*!
388                         @brief 無効化します。
389                     */
Disable()390                     void Disable() { dimension = 0; }
391                 };
392 
393             private :
394                 /*!
395                     @brief 属性を無効化します。
396 
397                     @param[in] bind_reg      バインドするレジスタを指定します。
398                 */
399                 void DisableAttr_( const bit32 bind_reg );
400 
401                 /*!
402                     @brief 属性を有効化するコマンドを生成します。
403 
404                     @param[in] command 描画コマンドの書き込み先の先頭アドレスです。
405 
406                     @return  書き込まれた描画コマンドの終端の次のアドレスを返します。
407                 */
408                 bit32* MakeEnableAttrCommand_( bit32* command ) const;
409 
410             private :
411                 mutable u32 m_CmdCacheVertexNum;
412                 mutable bit32 m_CmdCacheVertex[ VERTEX_ENABLE_COMMAND_MAX ];
413 
414                 bool        m_IsEnableReg[ VERTEX_ATTRIBUTE_MAX ];
415 
416                 LoadArray   m_LoadArray[ VERTEX_ATTRIBUTE_MAX ];
417                 AttrConst   m_AttrConst[ VERTEX_ATTRIBUTE_MAX ];
418             };
419 
420         }  // namespace CTR
421     }  // namespace gr
422 } // namespace nn
423 
424 
425 #endif // NN_GR_VERTEX_H_
426