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