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: 32402 $ 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] Format of the color buffer pixel size 29 // [18:16] Color buffer format 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] Color buffer physical address 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] Depth buffer format 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] Depth buffer physical address 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 // Clear frame buffer cache 69 if ( isClearCache ) 70 { 71 command = MakeClearCacheCommand( command ); 72 } 73 74 // Generate color buffer command 75 if ( bufferBit & COLOR_BUFFER_BIT ) 76 { 77 command = colorBuffer.MakeCommand( command ); 78 } 79 80 // Generate depth buffer command 81 if ( ( bufferBit & DEPTH_BUFFER_BIT ) || ( bufferBit & STENCIL_BUFFER_BIT ) ) 82 { 83 command = depthStencilBuffer.MakeCommand( command ); 84 } 85 86 // 0x11e 87 // [27:12] Frame buffer height 88 // [10: 0] Frame buffer width 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] Frame buffer height 94 // [10: 0] Frame buffer width 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, the size to fill, must be a multiple of 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 is clamped and converted to 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, the size to fill, must be a multiple of 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