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: 33699 $ 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 u8 red = FloatToUnsignedByte( colorBuffer.clearColor[ 0 ] ); 164 u8 green = FloatToUnsignedByte( colorBuffer.clearColor[ 1 ] ); 165 u8 blue = FloatToUnsignedByte( colorBuffer.clearColor[ 2 ] ); 166 167 if ( colorBuffer.format == PICA_DATA_COLOR_RGBA8_OES ) 168 { 169 u8 alpha = FloatToUnsignedByte( colorBuffer.clearColor[ 3 ] ); 170 171 colorByteSize = colorBuffer.width * colorBuffer.height * 4; 172 colorWidth = 32; 173 // float32 をクランプして、 u8 に変換します。 174 clearColor = ( red << 24 ) | 175 ( green << 16 ) | 176 ( blue << 8 ) | 177 ( alpha << 0 ) ; 178 } 179 else if ( colorBuffer.format == PICA_DATA_COLOR_RGB5_A1 ) 180 { 181 u8 alpha = FloatToUnsignedByte( colorBuffer.clearColor[ 3 ] ); 182 183 colorByteSize = colorBuffer.width * colorBuffer.height * 2; 184 colorWidth = 16; 185 clearColor = ( ( ( red >> 3 ) & 0x1f ) << 11 ) | 186 ( ( ( green >> 3 ) & 0x1f ) << 6 ) | 187 ( ( ( blue >> 3 ) & 0x1f ) << 1 ) | 188 ( ( ( alpha > 0x7f ) ? 0x1 : 0 ) << 0 ); 189 } 190 else if ( colorBuffer.format == PICA_DATA_COLOR_RGB565 ) 191 { 192 colorByteSize = colorBuffer.width * colorBuffer.height * 2; 193 colorWidth = 16; 194 clearColor = ( ( ( red >> 3 ) & 0x1f ) << 11 ) | 195 ( ( ( green >> 2 ) & 0x3f ) << 5 ) | 196 ( ( ( blue >> 3 ) & 0x1f ) << 0 ); 197 } 198 else if ( colorBuffer.format == PICA_DATA_COLOR_RGBA4 ) 199 { 200 u8 alpha = FloatToUnsignedByte( colorBuffer.clearColor[ 3 ] ); 201 202 colorByteSize = colorBuffer.width * colorBuffer.height * 2; 203 colorWidth = 16; 204 clearColor = ( ( ( red >> 4 ) & 0xf ) << 12 ) | 205 ( ( ( green >> 4 ) & 0xf ) << 8 ) | 206 ( ( ( blue >> 4 ) & 0xf ) << 4 ) | 207 ( ( ( alpha >> 4 ) & 0xf ) << 0 ); 208 } 209 } 210 211 // フィルするサイズ depthByteSize は 16 の倍数である必要があります。 212 u32 depthByteSize = 0; 213 u32 clearDepth = 0; 214 u32 depthWidth = 0; 215 216 if ( ( bufferBit & DEPTH_BUFFER_BIT ) || ( bufferBit & STENCIL_BUFFER_BIT ) ) 217 { 218 depthStencilBuffer.clearDepth = 219 ( depthStencilBuffer.clearDepth > 1.0f ) ? 1.0f : 220 ( ( depthStencilBuffer.clearDepth < 0.0f ) ? 0.0f : depthStencilBuffer.clearDepth ); 221 222 if ( depthStencilBuffer.format == PICA_DATA_DEPTH24_STENCIL8_EXT ) 223 { 224 depthByteSize = depthStencilBuffer.width * depthStencilBuffer.height * 4; 225 clearDepth = ( depthStencilBuffer.clearStencil ) << 24 | 226 Float32ToUnsignedFix24( depthStencilBuffer.clearDepth ); 227 depthWidth = 32; 228 } 229 else if ( depthStencilBuffer.format == PICA_DATA_DEPTH_COMPONENT16 ) 230 { 231 depthByteSize = depthStencilBuffer.width * depthStencilBuffer.height * 2; 232 clearDepth = Float32ToUnsignedFix16( depthStencilBuffer.clearDepth ); 233 depthWidth = 16; 234 } 235 else if ( depthStencilBuffer.format == PICA_DATA_DEPTH_COMPONENT24_OES ) 236 { 237 depthByteSize = depthStencilBuffer.width * depthStencilBuffer.height * 3; 238 clearDepth = Float32ToUnsignedFix24( depthStencilBuffer.clearDepth ); 239 depthWidth = 24; 240 } 241 } 242 243 if ( ( bufferBit & COLOR_BUFFER_BIT ) || ( bufferBit & DEPTH_BUFFER_BIT ) ) 244 { 245 if ( isAddSplitDrawCmdlist ) 246 { 247 nngxSplitDrawCmdlist(); 248 } 249 250 nngxAddMemoryFillCommand( 251 ( bufferBit & COLOR_BUFFER_BIT ) ? reinterpret_cast<GLvoid*>( colorBuffer.virtualAddr ) : 0, 252 colorByteSize, clearColor, colorWidth, 253 ( ( bufferBit & DEPTH_BUFFER_BIT ) || 254 ( bufferBit & STENCIL_BUFFER_BIT ) || 255 ( bufferBit & DEPTH_STENCIL_BUFFER_BIT ) ) ? 256 reinterpret_cast<GLvoid*>( depthStencilBuffer.virtualAddr ) : 0, 257 depthByteSize, clearDepth, depthWidth ); 258 } 259 } 260 261 } // namespace CTR 262 } // namespace gr 263 } // namespace nn 264