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