1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     gr_Utility.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_UTILITY_H_
17 #define NN_GR_UTILITY_H_
18 
19 #include <nn.h>
20 #include <nn/types.h>
21 #include <nn/gx.h>
22 #include <nn/gx/CTR/gx_CommandAccess.h>
23 
24 #include <nn/gr/CTR/gr_Prefix.h>
25 
26 namespace nn
27 {
28     namespace gr
29     {
30         namespace CTR
31         {
32 
33             //------------------------------------------------------------------------------
34 
35             /*!
36                 @brief 3x4行列をwHzyxの順に逆転してコピーします。(ヘッダーあり)
37 
38                 @param[in] dst 結果を書き込む先のポインタです。
39                 @param[in] src 34行列です。
40                 @param[in] header ヘッダです。
41             */
42             void CopyMtx34WithHeader(
43                 f32*  dst,
44                 const nn::math::MTX34* src,
45                 bit32   header );
46 
47             /*!
48                 @brief 4x4行列をwHzyxの順に逆転してコピーします。(ヘッダーあり)
49 
50                 @param[in] dst 結果を書き込む先のポインタです。
51                 @param[in] src 44行列です。
52                 @param[in] header ヘッダです。
53             */
54             void CopyMtx44WithHeader(
55                 f32* dst,
56                 const nn::math::MTX44* src,
57                 bit32 header );
58 
59             //------------------------------------------------------------------------------------
60 
61             /*!
62                  @brief 34行列を頂点シェーダのユニフォームにセットするコマンドを生成します。
63 
64                  @param[in] command      描画コマンドの書き込み先の先頭アドレスです。
65                  @param[in] location     レジスタの場所です。
66                  @param[in] mtx34        34行列です。
67 
68                  @return    書き込まれた描画コマンドの終端の次のアドレスを返します。
69              */
MakeUniformCommandVS(bit32 * command,u8 location,const nn::math::MTX34 & mtx34)70             inline bit32* MakeUniformCommandVS( bit32* command, u8 location, const nn::math::MTX34& mtx34 )
71             {
72                 *command++ = 0x80000000 | location;
73                 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_VS_FLOAT_ADDR );
74                 CopyMtx34WithHeader( (f32*)command, &mtx34, PICA_CMD_HEADER_VS_F32( 3 ) );
75                 return command + 14;
76             }
77 
78             //------------------------------------------------------------------------------------
79 
80             /*!
81                 @brief 44行列を頂点シェーダのユニフォームにセットするコマンドを生成します。
82 
83                 @param[in] command      描画コマンドの書き込み先の先頭アドレスです。
84                 @param[in] location     レジスタの場所です。
85                 @param[in] mtx44        44行列です。
86 
87                 @return    書き込まれた描画コマンドの終端の次のアドレスを返します。
88              */
MakeUniformCommandVS(bit32 * command,u8 location,const nn::math::MTX44 & mtx44)89             inline bit32* MakeUniformCommandVS( bit32* command, u8 location, const nn::math::MTX44& mtx44 )
90             {
91                 *command++ = 0x80000000 | location;
92                 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_VS_FLOAT_ADDR );
93                 CopyMtx44WithHeader( (f32*)command, &mtx44, PICA_CMD_HEADER_VS_F32( 4 ) );
94                 return command + 18;
95             }
96 
97             //------------------------------------------------------------------------------------
98 
99             /*!
100                 @brief ベクトルを頂点シェーダのユニフォームにセットするコマンドを生成します。
101 
102                 @param[in] command      描画コマンドの書き込み先の先頭アドレスです。
103                 @param[in] location     レジスタの場所です。
104                 @param[in] vec4         4次元のベクトルです。
105 
106                 @return    書き込まれた描画コマンドの終端の次のアドレスを返します。
107              */
MakeUniformCommandVS(bit32 * command,u8 location,const nn::math::VEC4 & vec4)108             inline bit32* MakeUniformCommandVS( bit32* command, u8 location, const nn::math::VEC4& vec4 )
109             {
110                 *command++ = 0x80000000 | location;
111                 *command++ = PICA_CMD_HEADER_BURSTSEQ( PICA_REG_VS_FLOAT_ADDR, 5 );
112                 *command++ = nn::math::F32AsU32( vec4.w );
113                 *command++ = nn::math::F32AsU32( vec4.z );
114                 *command++ = nn::math::F32AsU32( vec4.y );
115                 *command++ = nn::math::F32AsU32( vec4.x );
116                 return command;
117             }
118 
119 
120             //------------------------------------------------------------------------------------
121 
122             /*!
123                 @brief ベクトルの配列を頂点シェーダのユニフォームにセットするコマンドを生成します。
124 
125                 @param[in] command      描画コマンドの書き込み先の先頭アドレスです。
126                 @param[in] location     レジスタの場所です。
127                 @param[in] vec4         4次元のベクトルの配列です。
128                 @param[in] num          配列のサイズです。
129 
130                 @return    書き込まれた描画コマンドの終端の次のアドレスを返します。
131              */
MakeUniformCommandVS(bit32 * command,u8 location,const nn::math::VEC4 vec4[],const int num)132             inline bit32* MakeUniformCommandVS( bit32* command, u8 location, const nn::math::VEC4 vec4[], const int num )
133             {
134                 *command++ = 0x80000000 | location;
135                 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_VS_FLOAT_ADDR );
136                 *command++ = nn::math::F32AsU32( vec4[0].w );
137                 *command++ = PICA_CMD_HEADER_VS_F32( num );
138                 *command++ = nn::math::F32AsU32( vec4[0].z );
139                 *command++ = nn::math::F32AsU32( vec4[0].y );
140                 *command++ = nn::math::F32AsU32( vec4[0].x );
141 
142                 for ( int i = 1; i < num; ++i )
143                 {
144                     *command++ = nn::math::F32AsU32( vec4[i].w );
145                     *command++ = nn::math::F32AsU32( vec4[i].z );
146                     *command++ = nn::math::F32AsU32( vec4[i].y );
147                     *command++ = nn::math::F32AsU32( vec4[i].x );
148                 }
149 
150                 *command++ = 0; // padding
151 
152                 return command;
153             }
154 
155             //------------------------------------------------------------------------------------
156 
157             /*!
158                 @brief 整数を頂点シェーダのユニフォームにセットするコマンドを生成します。
159 
160                 @param[in] command      描画コマンドの書き込み先の先頭アドレスです。
161                 @param[in] location     レジスタの場所です。
162                 @param[in] x            x 座標の値です。
163                 @param[in] y            y 座標の値です。
164                 @param[in] z            z 座標の値です。
165 
166                 @return    書き込まれた描画コマンドの終端の次のアドレスを返します。
167              */
MakeUniformCommandVS(bit32 * command,u8 location,u8 x,u8 y,u8 z)168             inline bit32* MakeUniformCommandVS( bit32* command, u8 location, u8 x, u8 y, u8 z )
169             {
170                 *command++ = PICA_CMD_DATA_VS_INT( x, y, z );
171                 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_VS_INT0 + location );
172                 return command;
173             }
174 
175             //------------------------------------------------------------------------------------
176 
177             /*!
178                 @brief 34行列をジオメトリシェーダのユニフォームにセットするコマンドを生成します。
179 
180                 @param[in] command      描画コマンドの書き込み先の先頭アドレスです。
181                 @param[in] location     レジスタの場所です。
182                 @param[in] mtx34        34行列です。
183 
184                 @return    書き込まれた描画コマンドの終端の次のアドレスを返します。
185              */
MakeUniformCommandGS(bit32 * command,u8 location,const nn::math::MTX34 & mtx34)186             inline bit32* MakeUniformCommandGS( bit32* command, u8 location, const nn::math::MTX34& mtx34 )
187             {
188                 *command++ = 0x80000000 | location;
189                 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_GS_FLOAT_ADDR );
190                 CopyMtx34WithHeader( (f32*)command, &mtx34, PICA_CMD_HEADER_GS_F32( 3 ) );
191                 return command + 14;
192             }
193 
194             //------------------------------------------------------------------------------------
195 
196             /*!
197                 @brief 44行列をジオメトリシェーダのユニフォームにセットするコマンドを生成します。
198 
199                 @param[in] command      描画コマンドの書き込み先の先頭アドレスです。
200                 @param[in] location     レジスタの場所です。
201                 @param[in] mtx44        44行列です。
202 
203                 @return    書き込まれた描画コマンドの終端の次のアドレスを返します。
204              */
MakeUniformCommandGS(bit32 * command,u8 location,const nn::math::MTX44 & mtx44)205             inline bit32* MakeUniformCommandGS( bit32* command, u8 location, const nn::math::MTX44& mtx44 )
206             {
207                 *command++ = 0x80000000 | location;
208                 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_GS_FLOAT_ADDR );
209                 CopyMtx44WithHeader( (f32*)command, &mtx44, PICA_CMD_HEADER_GS_F32( 4 ) );
210                 return command + 18;
211             }
212 
213             //------------------------------------------------------------------------------------
214 
215             /*!
216                 @brief ベクトルをジオメトリシェーダのユニフォームにセットするコマンドを生成します.
217 
218                 @param[in] command      描画コマンドの書き込み先の先頭アドレスです。
219                 @param[in] location     レジスタの場所です。
220                 @param[in] vec4         4次元のベクトルです。
221 
222                 @return    書き込まれた描画コマンドの終端の次のアドレスを返します。
223              */
MakeUniformCommandGS(bit32 * command,u8 location,const nn::math::VEC4 & vec4)224             inline bit32* MakeUniformCommandGS( bit32* command, u8 location, const nn::math::VEC4& vec4 )
225             {
226                 *command++ = 0x80000000 | location;
227                 *command++ = PICA_CMD_HEADER_BURSTSEQ( PICA_REG_GS_FLOAT_ADDR, 5 );
228                 *command++ = nn::math::F32AsU32( vec4.w ); // a
229                 *command++ = nn::math::F32AsU32( vec4.z ); // b
230                 *command++ = nn::math::F32AsU32( vec4.y ); // g
231                 *command++ = nn::math::F32AsU32( vec4.x ); // r
232                 return command;
233             }
234 
235             //------------------------------------------------------------------------------------
236 
237             /*!
238                 @brief ベクトルの配列をジオメトリシェーダのユニフォームにセットするコマンドを生成します。
239 
240                 @param[in] command      描画コマンドの書き込み先の先頭アドレスです。
241                 @param[in] location     レジスタの場所です。
242                 @param[in] vec4         4次元のベクトルの配列です。
243                 @param[in] num          配列のサイズです。
244 
245                 @return    書き込まれた描画コマンドの終端の次のアドレスを返します。
246              */
MakeUniformCommandGS(bit32 * command,u8 location,const nn::math::VEC4 vec4[],const int num)247             inline bit32* MakeUniformCommandGS( bit32* command, u8 location, const nn::math::VEC4 vec4[], const int num )
248             {
249                 *command++ = 0x80000000 | location;
250                 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_GS_FLOAT_ADDR );
251                 *command++ = nn::math::F32AsU32( vec4[0].w );
252                 *command++ = PICA_CMD_HEADER_GS_F32( num );
253                 *command++ = nn::math::F32AsU32( vec4[0].z );
254                 *command++ = nn::math::F32AsU32( vec4[0].y );
255                 *command++ = nn::math::F32AsU32( vec4[0].x );
256 
257                 for ( int i = 1; i < num; ++i )
258                 {
259                     *command++ = nn::math::F32AsU32( vec4[i].w );
260                     *command++ = nn::math::F32AsU32( vec4[i].z );
261                     *command++ = nn::math::F32AsU32( vec4[i].y );
262                     *command++ = nn::math::F32AsU32( vec4[i].x );
263                 }
264 
265                 *command++ = 0; // padding
266 
267                 return command;
268             }
269 
270             //------------------------------------------------------------------------------------
271 
272             /*!
273                 @brief 整数をジオメトリシェーダのユニフォームにセットするコマンドを生成します。
274 
275                 @param[in] command      描画コマンドの書き込み先の先頭アドレスです。
276                 @param[in] location     レジスタの場所です。
277                 @param[in] x            x 座標の値です。
278                 @param[in] y            y 座標の値です。
279                 @param[in] z            z 座標の値です。
280 
281                 @return    書き込まれた描画コマンドの終端の次のアドレスを返します。
282              */
MakeUniformCommandGS(bit32 * command,u8 location,u8 x,u8 y,u8 z)283             inline bit32* MakeUniformCommandGS( bit32* command, u8 location, u8 x, u8 y, u8 z )
284             {
285                 *command++ = PICA_CMD_DATA_GS_INT( x, y, z );
286                 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_GS_INT0 + location );
287                 return command;
288             }
289 
290             //------------------------------------------------------------------------------------
291 
292             /*!
293                 @brief float32 を u8 に変換します。
294 
295                 @param[in] val      変換前の値です。
296 
297                 @return             変換後の値です。
298             */
FloatToUnsignedByte(f32 val)299             inline u8 FloatToUnsignedByte(
300                 f32 val
301                 )
302             {
303                 return ( u8 )( 0.5f + ( val < 0.f ? 0.f : ( 1.f < val ? 1.f : val ) )  * ( 0xff ) );
304             }
305 
306             //------------------------------------------------------------------------------------
307 
308             /*!
309                 @brief float32 を クランプせずに u8 に変換します。
310 
311                 @param[in] val      変換前の値です。
312 
313                 @return             変換後の値です
314             */
FloatToUnsignedByteNoClamp(f32 val)315             inline u8 FloatToUnsignedByteNoClamp(
316                 f32 val
317                 )
318             {
319                 return ( u8 )( 0.5f + val * 0xff );
320             }
321 
322             //------------------------------------------------------------------------------------
323 
324             /*!
325                 @brief float32 から float16 に変換します。
326 
327                 @param[in] val      変換前の値です。
328 
329                 @return             変換後の値です
330             */
Float32ToFloat16(f32 val)331             inline u16 Float32ToFloat16( f32 val )
332             {
333                 static const int bias_ = 128 - (1 << (5 - 1));
334 
335                 u32 uval_ = *(u32*)&val;
336                 int e_ = (uval_ & 0x7fffffff) ? (((uval_ >> 23) & 0xff) - bias_) : 0;
337                 if (e_ >= 0)
338                 {
339                     return ( u16 )( ((uval_ & 0x7fffff) >> (23 - 10)) | (e_ << 10) | ((uval_ >> 31) << (10 + 5)) );
340                 }
341                 return ( u16 )((uval_ >> 31) << (10 + 5));
342             }
343 
344             //------------------------------------------------------------------------------------
345 
346             /*!
347                 @brief float32 から float24 に変換します。
348 
349                 @param[in] val      変換前の値です。
350 
351                 @return             変換後の値です
352             */
Float32ToFloat24(f32 val)353             inline u32 Float32ToFloat24( f32 val )
354             {
355                 static const int bias_ = 128 - (1 << (7 - 1));
356                 u32 uval_   = *(unsigned*)&val;
357                 s32 e_      = (uval_ & 0x7fffffff) ? (((uval_ >> 23) & 0xff) - bias_) : 0;
358 
359                 return e_ >= 0 ? ((uval_ & 0x7fffff) >> (23 - 16)) | (e_ << 16) | ((uval_ >> 31) << (16 + 7)) : ((uval_ >> 31) << (16 + 7));
360             }
361 
362             //------------------------------------------------------------------------------------
363 
364             /*!
365                 @brief float32 から float20 に変換します。
366 
367                 @param[in] val      変換前の値です。
368 
369                 @return             変換後の値です
370             */
Float32ToFloat20(f32 val)371             inline u32 Float32ToFloat20( f32 val )
372             {
373                 static const int bias_ = 128 - (1 << (7 - 1));
374                 u32 uval_   = *(unsigned*)&val;
375                 s32 e_      = (uval_ & 0x7fffffff) ? (((uval_ >> 23) & 0xff) - bias_) : 0;
376 
377                 return e_ >= 0 ? ((uval_ & 0x7fffff) >> (23 - 12)) | (e_ << 12) | ((uval_ >> 31) << (12 + 7)) : ((uval_ >> 31) << (12 + 7));
378             }
379 
380             //------------------------------------------------------------------------------------
381 
382             /*!
383                 @brief float32 から float31 に変換します。
384 
385                 @param[in] val      変換前の値です。
386 
387                 @return             変換後の値です
388             */
Float32ToFloat31(f32 val)389             inline u32 Float32ToFloat31( f32 val )
390             {
391                 unsigned uval_, m_;
392                 int e_;
393                 float f_ = val;
394                 static const int bias_ = 128 - (1 << (7 - 1));
395                 uval_ = *(unsigned*)&f_;
396                 e_ = (uval_ & 0x7fffffff) ? (((uval_ >> 23) & 0xff) - bias_) : 0;
397                 m_ = (uval_ & 0x7fffff) >> (23 - 23);
398                 return e_ >= 0 ? m_ | (e_ << 23) | ((uval_ >> 31) << (23 + 7)) : ((uval_ >> 31) << (23 + 7));
399             }
400 
401             //------------------------------------------------------------------------------------
402             /*!
403                 @brief float32 から 符号なし fixed24 に変換します。
404 
405                 @param[in] val      変換前の値です。
406 
407                 @return             変換後の値です
408             */
Float32ToUnsignedFix24(f32 val)409             inline u32 Float32ToUnsignedFix24( f32 val )
410             {
411                 unsigned v_ = *(unsigned*)&val;
412 
413                 if (val <= 0 || (v_ & 0x7f800000) == 0x7f800000)
414                 {
415                     return 0;
416                 }
417                 else
418                 {
419                     val *= 1 << (24 - 0);
420 
421                     if ( val >= (1 << 24) )
422                     {
423                         return (1 << 24) - 1;
424                     }
425                     else
426                     {
427                         return (unsigned)(val);
428                     }
429                 }
430             }
431 
432             //------------------------------------------------------------------------------------
433             /*!
434                 @brief float32 から 符号なし fixed16 に変換します。
435 
436                 @param[in] val      変換前の値です。
437 
438                 @return             変換後の値です
439             */
Float32ToUnsignedFix16(f32 val)440             inline u32 Float32ToUnsignedFix16( f32 val )
441             {
442                 unsigned v_ = *(unsigned*)&val;
443 
444                 if (val <= 0 || (v_ & 0x7f800000) == 0x7f800000)
445                 {
446                     return 0;
447                 }
448                 else
449                 {
450                     val *= 1 << (16 - 0);
451                     if ( val >= (1 << 16) )
452                     {
453                                 return (1 << 16) - 1;
454                     }
455                     else
456                     {
457                                 return (unsigned)( val );
458                     }
459                 }
460             }
461 
462             //------------------------------------------------------------------------------------
463             /*!
464                 @brief float32 から 符号あり fixed16 に変換します。
465 
466                 @param[in] val      変換前の値です。
467 
468                 @return             変換後の値です
469             */
Float32ToFix16(f32 val)470             inline u16 Float32ToFix16( f32 val )
471             {
472                 unsigned v_ = *(unsigned*) &val;
473 
474                 if ( (val == 0.f) || ( (v_ & 0x7f800000) == 0x7f800000 ) )
475                 {
476                     return 0;
477                 }
478                 else
479                 {
480                     val += 0.5f * (1 << 4);
481                     val *= 1 << (16 - 4);
482                     if (val < 0)
483                     {
484                         val = 0;
485                     }
486                     else if (val >= (1 << 16))
487                     {
488                         val = (1 << 16) - 1;
489                     }
490 
491                     if (val >= (1 << (16 - 1)))
492                     {
493                         return (unsigned)(val - (1 << (16 - 1)));
494                     }
495                     else
496                     {
497                         return (unsigned)(val + (1 << (16 - 1)));
498                     }
499                 }
500             }
501 
502             //------------------------------------------------------------------------------------
503 
504             /*!
505                 @brief float32 から 符号なし fixed12 に変換します。
506 
507                 @param[in] val      変換前の値です。
508 
509                 @return             変換後の値です
510             */
Float32ToUnsignedFix12(f32 val)511             inline u32 Float32ToUnsignedFix12( f32 val )
512             {
513                 unsigned v_ = *(unsigned*)&val;
514                 if( val <= 0 || (v_ & 0x7f800000) == 0x7f800000 )
515                 {
516                     return 0;
517                 }
518                 else
519                 {
520                     unsigned uval_;
521 
522                     val *= 1 << (12 - 0);
523                     if (val >= (1 << 12))
524                     {
525                         uval_ = (1 << 12) - 1;
526                     }
527                     else
528                     {
529                         uval_ = (unsigned)(val);
530                     }
531 
532                     return uval_;
533                 }
534             }
535 
536             //------------------------------------------------------------------------------------
537 
538             /*!
539                 @brief float32 から 符号あり fixed12 に変換します。
540 
541                 @param[in] val      変換前の値です。
542 
543                 @return             変換後の値です
544             */
Float32ToFix12(f32 val)545             inline u32 Float32ToFix12( f32 val )
546             {
547                 unsigned v_ = *(unsigned*)&val;
548                 if( val == 0.f || (v_ & 0x7f800000) == 0x7f800000 )
549                     return 0;
550 
551                 int ret;
552 
553                 val *= (1 << (12 - 1));
554 
555                 if( val < 0 )
556                 {
557                     ret = 1 << (12 - 1);
558                     val = -val;
559                 }
560                 else
561                     ret = 0;
562 
563                 if( val >= (1 << (12 - 1)) )
564                     val  = (1 << (12 - 1)) - 1;
565 
566                 ret |= (unsigned)(val);
567                 return ret;
568             }
569 
570             /*!
571                 @brief float32 から fixed12 ( fraction 11) に変換します。
572 
573                 @param[in] val      変換前の値です。
574 
575                 @return             変換後の値です
576             */
Float32ToFix12Fraction11(f32 val)577             inline u32 Float32ToFix12Fraction11( f32 val )
578             {
579                 unsigned v_ = *(unsigned*)&val;
580 
581                 if (val == 0.f || (v_ & 0x7f800000) == 0x7f800000)
582                 {
583                     return 0;
584                 }
585                 else
586                 {
587                     val += 0.5f * (1 << 1);
588                     val *= 1 << (12 - 1);
589 
590                     if (val < 0)
591                     {
592                         val = 0;
593                     }
594                     else if (val >= (1 << 12))
595                     {
596                             val = (1 << 12) - 1;
597                     }
598 
599                     if (val >= (1 << (12 - 1)))
600                     {
601                         return (unsigned)(val - (1 << (12 - 1)));
602                     }
603                     else
604                     {
605                         return (unsigned)(val + (1 << (12 - 1)));
606                     }
607                 }
608             }
609 
610             //------------------------------------------------------------------------------------
611 
612             /*!
613                 @brief float32 から fixed13 ( fraction 8) に変換します。
614 
615                 @param[in] val      変換前の値です。
616 
617                 @return             変換後の値です
618             */
Float32ToFix13Fraction8(f32 val)619             inline u32 Float32ToFix13Fraction8( f32 val )
620             {
621                 unsigned v_ = *(unsigned*)&val;
622                 if ( ( val == 0.0f ) ||
623                      ( (v_ & 0x7f800000) == 0x7f800000 ) )
624                 {
625                     return 0;
626                 }
627 
628                 val += 0.5f * (1 << 5);
629                 val *= 1 << (13 - 5);
630                 if (val < 0)
631                 {
632                     val = 0;
633                 }
634                 else if (val >= (1 << 13))
635                 {
636                     val = (1 << 13) - 1;
637                 }
638 
639                 return (val >= (1 << (13 - 1))) ? (unsigned)(val - (1 << (13 - 1))) : (unsigned)(val + (1 << (13 - 1)));
640             }
641 
642             //------------------------------------------------------------------------------------
643 
644             /*!
645                 @brief float32 から fixed11 ( fraction 8) に変換します。
646 
647                 @param[in] val      変換前の値です。
648 
649                 @return             変換後の値です
650             */
Float32ToFix13Fraction11(f32 val)651             inline u32 Float32ToFix13Fraction11( f32 val )
652             {
653                 unsigned v_ = *(unsigned*)&val;
654                 if( val == 0.f || (v_ & 0x7f800000) == 0x7f800000 )
655                     return 0;
656 
657                 val += 0.5f * (1 << 2);
658                 val *= 1 << (13 - 2);
659                 if (val < 0)
660                     val = 0;
661                 else if (val >= (1 << 13))
662                     val = (1 << 13) - 1;
663 
664                 return (val >= (1 << (13 - 1))) ? (unsigned)(val - (1 << (13 - 1))) : (unsigned)(val + (1 << (13 - 1)));
665             }
666 
667             //------------------------------------------------------------------------------------
668 
669             /*!
670                 @brief float32 から 符号無し fixed11 に変換します。
671 
672                 @param[in] val      変換前の値です。
673 
674                 @return             変換後の値です
675             */
Float32ToUnsignedFix11(f32 val)676             inline u32 Float32ToUnsignedFix11( f32 val )
677             {
678                 unsigned v_ = *(unsigned*)&val;
679                 if( val <= 0 || (v_ & 0x7f800000) == 0x7f800000 )
680                     return 0;
681 
682                 unsigned uval_;
683 
684                 val *= 1 << (11 - 0);
685                 if (val >= (1 << 11))
686                     uval_ = (1 << 11) - 1;
687                 else
688                     uval_ = (unsigned)(val);
689 
690                 return uval_;
691             }
692 
693              //------------------------------------------------------------------------------------
694 
695             /*!
696                 @brief float32 から fixed8 ( 7bits fraction ) に変換します。
697 
698                 @param[in] val      変換前の値です。
699 
700                 @return             変換後の値です
701             */
Float32ToFix8Fraction7(f32 val)702             inline u8 Float32ToFix8Fraction7( f32 val )
703             {
704                 unsigned v_ = *(unsigned*)&val;
705 
706                 if (val == 0.f || (v_ & 0x7f800000) == 0x7f800000)
707                 {
708                     return 0;
709                 }
710                 else
711                 {
712                     val += 0.5f * (1 << 1);
713                     val *= 1 << (8 - 1);
714 
715                     if (val < 0)
716                     {
717                         val = 0;
718                     }
719                     else if (val >= (1 << 8))
720                     {
721                         val = (1 << 8) - 1;
722                     }
723 
724                     if (val >= (1 << (8 - 1)))
725                     {
726                         return (unsigned)(val - (1 << (8 - 1)));
727                     }
728                     else
729                     {
730                         return (unsigned)(val + (1 << (8 - 1)));
731                     }
732                 }
733             }
734 
735             //------------------------------------------------------------------------------------
736 
737             /*!
738                 @brief 頂点配列の型から、バイトサイズを求めます。
739 
740                 @param[in] type      頂点配列の型です。
741 
742                 @return             バイトサイズです。
743             */
PicaDataVertexAttrTypeToByteSize(const PicaDataVertexAttrType type)744             inline u32 PicaDataVertexAttrTypeToByteSize( const PicaDataVertexAttrType type )
745             {
746                 switch ( type )
747                 {
748                     case PICA_DATA_SIZE_1_BYTE          : return 1 * sizeof(  s8 );
749                     case PICA_DATA_SIZE_1_UNSIGNED_BYTE : return 1 * sizeof(  u8 );
750                     case PICA_DATA_SIZE_1_SHORT         : return 1 * sizeof( s16 );
751                     case PICA_DATA_SIZE_1_FLOAT         : return 1 * sizeof( f32 );
752                     case PICA_DATA_SIZE_2_BYTE          : return 2 * sizeof(  s8 );
753                     case PICA_DATA_SIZE_2_UNSIGNED_BYTE : return 2 * sizeof(  u8 );
754                     case PICA_DATA_SIZE_2_SHORT         : return 2 * sizeof( s16 );
755                     case PICA_DATA_SIZE_2_FLOAT         : return 2 * sizeof( f32 );
756                     case PICA_DATA_SIZE_3_BYTE          : return 3 * sizeof(  s8 );
757                     case PICA_DATA_SIZE_3_UNSIGNED_BYTE : return 3 * sizeof(  u8 );
758                     case PICA_DATA_SIZE_3_SHORT         : return 3 * sizeof( s16 );
759                     case PICA_DATA_SIZE_3_FLOAT         : return 3 * sizeof( f32 );
760                     case PICA_DATA_SIZE_4_BYTE          : return 4 * sizeof(  s8 );
761                     case PICA_DATA_SIZE_4_UNSIGNED_BYTE : return 4 * sizeof(  u8 );
762                     case PICA_DATA_SIZE_4_SHORT         : return 4 * sizeof( s16 );
763                     case PICA_DATA_SIZE_4_FLOAT         : return 4 * sizeof( f32 );
764                 }
765                 return 0;
766             }
767 
768         } // namespace CTR
769     } // namespace gr
770 } // namespace nn
771 
772 #endif // NN_GR_UTILITY_H_
773