1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     gr_FrameBuffer.cpp
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: 31028 $
14  *---------------------------------------------------------------------------*/
15 
16 #include <nn/gr/CTR/gr_FrameBuffer.h>
17 
18 namespace nn
19 {
20     namespace gr
21     {
22         namespace CTR
23         {
24 
MakeCommand(bit32 * command) const25             bit32* FrameBuffer::ColorBuffer::MakeCommand( bit32* command ) const
26             {
27                 // 0x117
28                 //   [ 1: 0] カラーバッファのピクセルサイズのフォーマット
29                 //   [18:16] カラーバッファのフォーマット
30                 *command++ =
31                     PICA_CMD_DATA_RENDER_BUFFER_COLOR_MODE(
32                         ( ( format == PICA_DATA_COLOR_RGBA8_OES ) |
33                           ( format == PICA_DATA_COLOR_GAS_DMP   ) ) ?
34                           PICA_DATA_COLOR_PIXEL_SIZE32 : PICA_DATA_COLOR_PIXEL_SIZE16,
35                           format );
36                 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_RENDER_BUFFER_COLOR_MODE );
37 
38                 // 0x11d
39                 //   [27: 0]  カラーバッファの物理アドレス
40                 *command++ = PICA_CMD_DATA_RENDER_BUFFER_COLOR_ADDR( nngxGetPhysicalAddr( virtualAddr ) );
41                 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_RENDER_BUFFER_COLOR_ADDR );
42 
43                 return command;
44             }
45 
46             //------------------------------------------------------------------------------
47 
MakeCommand(bit32 * command) const48             bit32* FrameBuffer::DepthStencilBuffer::MakeCommand( bit32* command ) const
49             {
50                 // 0x116
51                 //   [ 1: 0] デプスバッファのフォーマット
52                 *command++ = PICA_CMD_DATA_RENDER_BUFFER_DEPTH_MODE( format );
53                 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_RENDER_BUFFER_DEPTH_MODE );
54 
55                 // 0x11c
56                 //   [27: 0] デプスバッファの物理アドレス
57                 *command++ = PICA_CMD_DATA_RENDER_BUFFER_DEPTH_ADDR( nngxGetPhysicalAddr( virtualAddr ) );
58                 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_RENDER_BUFFER_DEPTH_ADDR );
59 
60                 return command;
61             }
62 
63             //------------------------------------------------------------------------------
64 
MakeCommand(bit32 * command,const u32 bufferBit,bool isClearCache) const65             bit32* FrameBuffer::FrameBuffer::MakeCommand( bit32* command, const u32 bufferBit,
66                                                           bool isClearCache ) const
67             {
68                 // フレームバッファのキャッシュクリア
69                 if ( isClearCache )
70                 {
71                     command = MakeClearCacheCommand( command );
72                 }
73 
74                 // カラーバッファのコマンドの生成
75                 if ( bufferBit & COLOR_BUFFER_BIT )
76                 {
77                     command = colorBuffer.MakeCommand( command );
78                 }
79 
80                 // デプスバッファのコマンドの生成
81                 if ( ( bufferBit & DEPTH_BUFFER_BIT ) || ( bufferBit & STENCIL_BUFFER_BIT ) )
82                 {
83                     command = depthStencilBuffer.MakeCommand( command );
84                 }
85 
86                 // 0x11e
87                 //   [27:12] フレームバッファの高さ
88                 //   [10: 0] フレームバッファの幅
89                 *command++ = PICA_CMD_DATA_RENDER_BUFFER_RESOLUTION( width, height );
90                 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_RENDER_BUFFER_RESOLUTION0 );
91 
92                 // 0x6e
93                 //   [27:12] フレームバッファの高さ
94                 //   [10: 0] フレームバッファの幅
95                 *command++ = PICA_CMD_DATA_RENDER_BUFFER_RESOLUTION( width, height );
96                 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_RENDER_BUFFER_RESOLUTION1 );
97 
98                 command = MakeClearCacheCommand( command );
99 
100                 return command;
101             }
102 
103             //------------------------------------------------------------------------------
104 
ColorBuffer(const FrameBuffer & frameBuffer_)105             FrameBuffer::ColorBuffer::ColorBuffer( const FrameBuffer& frameBuffer_ )
106                 : virtualAddr( 0 ),
107                   format( PICA_DATA_COLOR_RGBA8_OES ),
108                   blockSize( BLOCK_SIZE8 ),
109                   width( 240 ), height( 400 ),
110                   m_FrameBuffer( frameBuffer_ )
111             {
112                 for (u32 index = 0; index < 4; index++)
113                 {
114                     clearColor[ index ] = 0.0f;
115                 }
116             }
117 
118             //------------------------------------------------------------------------------
119 
DepthStencilBuffer(const FrameBuffer & frameBuffer_)120             FrameBuffer::DepthStencilBuffer::DepthStencilBuffer( const FrameBuffer& frameBuffer_ )
121                 : virtualAddr( 0 ),
122                 format( PICA_DATA_DEPTH24_STENCIL8_EXT ),
123                 width( 240 ), height( 400 ),
124                 clearDepth( 1.0f ),
125                 clearStencil( 0 ),
126                 m_FrameBuffer( frameBuffer_ )
127             {
128             }
129 
130             //------------------------------------------------------------------------------
131 
FrameBuffer()132             FrameBuffer::FrameBuffer() :
133                   colorBuffer( *this ),
134                   depthStencilBuffer( *this ),
135                   width( 240 ), height( 400 )
136             {
137             }
138 
139             //------------------------------------------------------------------------------
140 
MakeClearCacheCommand(bit32 * command)141             bit32* FrameBuffer::MakeClearCacheCommand( bit32* command )
142             {
143                 // 0x111
144                 *command++ = 0x1;
145                 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_COLOR_DEPTH_BUFFER_CLEAR1 );
146 
147                 // 0x110
148                 *command++ = 0x1;
149                 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_COLOR_DEPTH_BUFFER_CLEAR0 );
150 
151                 return command;
152             }
153 
MakeClearRequest(const u32 bufferBit,bool isAddSplitDrawCmdlist)154             void FrameBuffer::FrameBuffer::MakeClearRequest( const u32 bufferBit, bool isAddSplitDrawCmdlist )
155             {
156                 // フィルするサイズ colorByteSize は 16 の倍数である必要があります。
157                 u32 colorByteSize = 0;
158                 u32 colorWidth    = 0;
159                 u32 clearColor    = 0;
160 
161                 if ( bufferBit & COLOR_BUFFER_BIT )
162                 {
163                     if ( colorBuffer.format == PICA_DATA_COLOR_RGBA8_OES )
164                     {
165                         colorByteSize = colorBuffer.width * colorBuffer.height * 4;
166                         colorWidth    = 32;
167                         // float32 をクランプして、 u8 に変換します。
168                         clearColor    = ( FloatToUnsignedByte( colorBuffer.clearColor[ 0 ] ) << 24 ) |
169                                         ( FloatToUnsignedByte( colorBuffer.clearColor[ 1 ] ) << 16 ) |
170                                         ( FloatToUnsignedByte( colorBuffer.clearColor[ 2 ] ) <<  8 ) |
171                                         ( FloatToUnsignedByte( colorBuffer.clearColor[ 3 ] ) <<  0 ) ;
172                     }
173                     else if ( colorBuffer.format == PICA_DATA_COLOR_RGB5_A1 )
174                     {
175                         colorByteSize = colorBuffer.width * colorBuffer.height * 2;
176                         colorWidth    = 16;
177                         clearColor    = ( ( ( FloatToUnsignedByte( colorBuffer.clearColor[ 0 ] ) >> 3 ) & 0x1f ) << 11 ) |
178                                         ( ( ( FloatToUnsignedByte( colorBuffer.clearColor[ 1 ] ) >> 3 ) & 0x1f ) <<  6 ) |
179                                         ( ( ( FloatToUnsignedByte( colorBuffer.clearColor[ 2 ] ) >> 3 ) & 0x1f ) <<  1 ) |
180                                         ( ( FloatToUnsignedByte( colorBuffer.clearColor[ 3 ] ) > 0x7f ) ? 0x1 : 0 );
181                     }
182                     else if ( colorBuffer.format == PICA_DATA_COLOR_RGB565 )
183                     {
184                         colorByteSize = colorBuffer.width * colorBuffer.height * 18 / 8;
185                         colorWidth    = 16;
186                         clearColor    = ( ( ( FloatToUnsignedByte( colorBuffer.clearColor[ 0 ] ) >> 3 ) & 0x1f ) << 11 ) |
187                                           ( ( ( FloatToUnsignedByte( colorBuffer.clearColor[ 1 ] ) >> 2 ) & 0x3f ) <<  6 ) |
188                                           ( ( ( FloatToUnsignedByte( colorBuffer.clearColor[ 2 ] ) >> 3 ) & 0x1f ) <<  0 );
189                     }
190                     else if ( colorBuffer.format == PICA_DATA_COLOR_RGBA4 )
191                     {
192                         colorByteSize = colorBuffer.width * colorBuffer.height * 12 / 8;
193                         colorWidth    = 16;
194                         clearColor    = ( ( ( FloatToUnsignedByte( colorBuffer.clearColor[ 0 ] ) >> 4 ) & 0xf ) << 12 ) |
195                                           ( ( ( FloatToUnsignedByte( colorBuffer.clearColor[ 1 ] ) >> 4 ) & 0xf ) <<  8 ) |
196                                           ( ( ( FloatToUnsignedByte( colorBuffer.clearColor[ 2 ] ) >> 4 ) & 0xf ) <<  4 );
197                     }
198                 }
199 
200                 // フィルするサイズ depthByteSize は 16 の倍数である必要があります。
201                 u32 depthByteSize = 0;
202                 u32 clearDepth    = 0;
203                 u32 depthWidth    = 0;
204 
205                 if ( ( bufferBit & DEPTH_BUFFER_BIT ) || ( bufferBit & STENCIL_BUFFER_BIT ) )
206                 {
207                     depthStencilBuffer.clearDepth =
208                         ( depthStencilBuffer.clearDepth > 1.0f ) ? 1.0f :
209                         ( ( depthStencilBuffer.clearDepth < 0.0f ) ? 0.0f : depthStencilBuffer.clearDepth );
210 
211                     if ( depthStencilBuffer.format == PICA_DATA_DEPTH24_STENCIL8_EXT )
212                     {
213                         depthByteSize = depthStencilBuffer.width * depthStencilBuffer.height * 4;
214                         clearDepth    = ( depthStencilBuffer.clearStencil & 0xff ) << 24 |
215                                         Float32ToUnsignedFix24( depthStencilBuffer.clearDepth );
216                         depthWidth    = 32;
217                     }
218                     else if ( depthStencilBuffer.format == PICA_DATA_DEPTH_COMPONENT16 )
219                     {
220                         depthByteSize = depthStencilBuffer.width * depthStencilBuffer.height * 2;
221                         clearDepth    = Float32ToUnsignedFix16( depthStencilBuffer.clearDepth );
222                         depthWidth    = 16;
223                     }
224                     else if ( depthStencilBuffer.format == PICA_DATA_DEPTH_COMPONENT24_OES )
225                     {
226                         depthByteSize = depthStencilBuffer.width * depthStencilBuffer.height * 3;
227                         clearDepth    = Float32ToUnsignedFix24( depthStencilBuffer.clearDepth );
228                         depthWidth    = 24;
229                     }
230                 }
231 
232                 if ( ( bufferBit & COLOR_BUFFER_BIT ) || ( bufferBit & DEPTH_BUFFER_BIT ) )
233                 {
234                     if ( isAddSplitDrawCmdlist )
235                     {
236                         nngxSplitDrawCmdlist();
237                     }
238 
239                     nngxAddMemoryFillCommand(
240                         ( bufferBit & COLOR_BUFFER_BIT ) ? reinterpret_cast<GLvoid*>( colorBuffer.virtualAddr ) : 0,
241                         colorByteSize, clearColor, colorWidth,
242                         ( ( bufferBit & DEPTH_BUFFER_BIT ) || ( bufferBit & DEPTH_STENCIL_BUFFER_BIT ) ) ?
243                           reinterpret_cast<GLvoid*>( depthStencilBuffer.virtualAddr ) : 0,
244                         depthByteSize, clearDepth, depthWidth );
245                 }
246             }
247 
248         } // namespace CTR
249     } // namespace gr
250 } // namespace nn
251