1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: gr_RenderState.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: 25760 $ 14 *---------------------------------------------------------------------------*/ 15 16 #include <nn/gr/CTR/gr_RenderState.h> 17 18 namespace nn 19 { 20 namespace gr 21 { 22 namespace CTR 23 { 24 MakeCommand(u32 * command,bool isUpdateFBAccess) const25 u32* RenderState::Culling::MakeCommand( u32* command, bool isUpdateFBAccess ) const 26 { 27 u32 culling = 0; 28 29 if ( isEnable ) 30 { 31 if ( ( frontFace == FRONT_FACE_CW && cullFace == CULL_FACE_FRONT ) || 32 ( frontFace == FRONT_FACE_CCW && cullFace == CULL_FACE_BACK ) ) 33 { 34 culling = 2; 35 } 36 else 37 { 38 culling = 1; 39 } 40 } 41 42 // 0x040 43 *command++ = culling; 44 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_CULL_FACE ); 45 46 return isUpdateFBAccess ? m_RenderState.fbAccess.MakeCommand( command ) : command; 47 } 48 49 //------------------------------------------------------------------------------ 50 MakeCommand(u32 * command,bool isUpdateFBAccess) const51 u32* RenderState::Blend::MakeCommand( u32* command, bool isUpdateFBAccess ) const 52 { 53 if ( isEnable ) 54 { 55 // 0x100 56 *command++ = PICA_CMD_DATA_COLOR_OPERATION( PICA_DATA_FRAGOP_MODE_DMP, PICA_DATA_ENABLE_BLEND ); 57 *command++ = PICA_CMD_HEADER_SINGLE_BE( PICA_REG_COLOR_OPERATION, 0x3 ); 58 59 // 0x101 60 *command++ = PICA_CMD_DATA_BLEND_FUNC_SEPARATE( eqRgb, eqAlpha, srcRgb, dstRgb, srcAlpha, dstAlpha ); 61 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_BLEND_FUNC ); 62 63 // 0x102 64 *command++ = PICA_CMD_DATA_LOGIC_OP( PICA_DATA_LOGIC_NOOP ); 65 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_LOGIC_OP ); 66 67 // 0x103 68 *command++ = colorR | colorG << 8 | colorB << 16 | colorA << 24; 69 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_BLEND_COLOR ); 70 } 71 else 72 { 73 // 0x100 74 *command++ = PICA_CMD_DATA_COLOR_OPERATION( PICA_DATA_FRAGOP_MODE_DMP, PICA_DATA_ENABLE_BLEND ); 75 *command++ = PICA_CMD_HEADER_SINGLE_BE( PICA_REG_COLOR_OPERATION, 0x3 ); 76 77 // 0x101 78 *command++ = PICA_CMD_DATA_BLEND_FUNC( PICA_DATA_BLEND_EQUATION_ADD, PICA_DATA_BLEND_FUNC_ONE, PICA_DATA_BLEND_FUNC_ZERO ); 79 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_BLEND_FUNC ); 80 } 81 82 return isUpdateFBAccess ? m_RenderState.fbAccess.MakeCommand( command ) : command; 83 } 84 85 //------------------------------------------------------------------------------ 86 MakeCommand(u32 * command,bool isUpdateFBAccess) const87 u32* RenderState::LogicOp::MakeCommand( u32* command, bool isUpdateFBAccess ) const 88 { 89 if ( isEnable ) 90 { 91 // 0x100 92 *command++ = PICA_CMD_DATA_COLOR_OPERATION( PICA_DATA_FRAGOP_MODE_DMP, PICA_DATA_ENABLE_COLOR_LOGIC_OP ); 93 *command++ = PICA_CMD_HEADER_SINGLE_BE( PICA_REG_COLOR_OPERATION, 0x3 ); 94 95 // 0x101 96 *command++ = PICA_CMD_DATA_LOGIC_OP_ENABLE(); 97 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_BLEND_FUNC ); 98 99 // 0x102 100 *command++ = PICA_CMD_DATA_LOGIC_OP( opCode ); 101 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_LOGIC_OP ); 102 } 103 104 return isUpdateFBAccess ? m_RenderState.fbAccess.MakeCommand( command ) : command; 105 } 106 107 //------------------------------------------------------------------------------ 108 MakeCommand(u32 * command,bool isUpdateFBAccess) const109 u32* RenderState::AlphaTest::MakeCommand( u32* command, bool isUpdateFBAccess ) const 110 { 111 // 0x104 112 *command++ = PICA_CMD_DATA_FRAGOP_ALPHA_TEST( isEnable, func, refValue ); 113 *command++ = PICA_CMD_HEADER_SINGLE_BE( PICA_REG_FRAGOP_ALPHA_TEST, 0x3 ); 114 115 return isUpdateFBAccess ? m_RenderState.fbAccess.MakeCommand( command ) : command; 116 } 117 118 //------------------------------------------------------------------------------ 119 MakeCommand(u32 * command,bool isUpdateFBAccess) const120 u32* RenderState::StencilTest::MakeCommand( u32* command, bool isUpdateFBAccess ) const 121 { 122 // 0x105 123 *command++ = PICA_CMD_DATA_STENCIL_TEST( isEnable, func, isEnableWrite, ref, mask ); 124 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_STENCIL_TEST ); 125 126 // 0x106 127 *command++ = PICA_CMD_DATA_STENCIL_OP( opFail, opZFail, opZPass ); 128 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_STENCIL_OP ); 129 130 return isUpdateFBAccess ? m_RenderState.fbAccess.MakeCommand( command ) : command; 131 } 132 133 //------------------------------------------------------------------------------ 134 MakeCommand(u32 * command,bool isUpdateFBAccess) const135 u32* RenderState::DepthTest::MakeCommand( u32* command, bool isUpdateFBAccess ) const 136 { 137 // 0x107の[ 0:7 ]と[12:12]がデプステストの設定で、[8:11]がカラーマスクの設定です。 138 *command++ = PICA_CMD_DATA_DEPTH_COLOR_MASK( isEnable, 139 func, 140 m_RenderState.colorMask & COLOR_MASK_R, 141 m_RenderState.colorMask & COLOR_MASK_G, 142 m_RenderState.colorMask & COLOR_MASK_B, 143 m_RenderState.colorMask & COLOR_MASK_A, 144 isEnableWrite ); 145 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_DEPTH_COLOR_MASK ); 146 147 return isUpdateFBAccess ? m_RenderState.fbAccess.MakeCommand( command ) : command; 148 } 149 150 //------------------------------------------------------------------------------ 151 MakeCommand(u32 * command,bool isUpdateFBAccess) const152 u32* RenderState::WBuffer::MakeCommand( u32* command, bool isUpdateFBAccess ) const 153 { 154 if ( wScale == 0.f ) 155 { 156 // 0x6d 157 *command++ = 1; 158 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAGOP_WSCALE ); 159 160 // 0x04d 161 *command++ = Float32ToFloat24( depthRangeNear - depthRangeFar ); 162 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAGOP_WSCALE_DATA1 ); 163 164 // 0x04e 165 f32 zNear = isEnablePolygonOffset ? depthRangeNear - (depthRangeNear - depthRangeFar) * polygonOffsetUnit / f32(1 << depthRangeBit - 1) : depthRangeNear; 166 *command++ = Float32ToFloat24( zNear ); 167 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAGOP_WSCALE_DATA2 ); 168 } 169 else 170 { 171 // 0x6d 172 *command++ = 0; 173 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAGOP_WSCALE ); 174 175 // 0x04d 176 *command++ = Float32ToFloat24( -wScale ); 177 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAGOP_WSCALE_DATA1 ); 178 179 // 0x04e 180 *command++ = 0; 181 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAGOP_WSCALE_DATA2 ); 182 } 183 184 return isUpdateFBAccess ? m_RenderState.fbAccess.MakeCommand( command ) : command; 185 } 186 187 //------------------------------------------------------------------------------ 188 MakeCommand(u32 * command) const189 u32* RenderState::FBAccess::MakeCommand( u32* command ) const 190 { 191 // 0x111 192 *command++ = 1; 193 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_COLOR_DEPTH_BUFFER_CLEAR1 ); 194 195 // 0x110 196 *command++ = 1; 197 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_COLOR_DEPTH_BUFFER_CLEAR0 ); 198 199 // 0x112 200 *command++ = ( (m_RenderState.colorMask && m_RenderState.colorMask != 0xf) || 201 (m_RenderState.colorMask && m_RenderState.blend.isEnable ) || 202 (m_RenderState.colorMask && m_RenderState.logicOp.isEnable ) ) ? 0xf : 0; 203 *command++ = PICA_CMD_HEADER_SINGLE_BE( PICA_REG_COLOR_BUFFER_READ, 0x1 ); 204 205 // 0x113 206 *command++ = m_RenderState.colorMask ? 0xf : 0; 207 *command++ = PICA_CMD_HEADER_SINGLE_BE( PICA_REG_COLOR_BUFFER_WRITE, 0x1 ); 208 209 u32 depth_stencil_read = 0; 210 u32 depth_stencil_write = 0; 211 212 if ( m_RenderState.depthTest.isEnable ) 213 { 214 if ( m_RenderState.depthTest.isEnableWrite ) { depth_stencil_read |= 2; depth_stencil_write |= 2; } 215 else if ( m_RenderState.colorMask ) { depth_stencil_read |= 2; } 216 } 217 218 if ( m_RenderState.stencilTest.isEnable ) 219 { 220 if ( m_RenderState.stencilTest.isEnableWrite ) { depth_stencil_read |= 1; depth_stencil_write |= 1; } 221 else if ( m_RenderState.colorMask ) { depth_stencil_read |= 1; } 222 } 223 224 // 0x114 225 *command++ = depth_stencil_read; 226 *command++ = PICA_CMD_HEADER_SINGLE_BE( PICA_REG_DEPTH_STENCIL_BUFFER_READ, 0x1 ); 227 228 // 0x115 229 *command++ = depth_stencil_write; 230 *command++ = PICA_CMD_HEADER_SINGLE_BE( PICA_REG_DEPTH_STENCIL_BUFFER_WRITE, 0x1 ); 231 232 return command; 233 } 234 235 //------------------------------------------------------------------------------ 236 MakeCommand(u32 * buffer) const237 u32* RenderState::RenderState::MakeCommand( u32* buffer ) const 238 { 239 u32* command = buffer; 240 241 command = cullingTest.MakeCommand( command, false ); 242 command = blend.MakeCommand( command, false ); 243 command = logicOp.MakeCommand( command, false ); 244 command = alphaTest.MakeCommand( command, false ); 245 command = stencilTest.MakeCommand( command, false ); 246 command = depthTest.MakeCommand( command, false ); 247 command = wBuffer.MakeCommand( command, false ); 248 command = fbAccess.MakeCommand( command ); 249 250 return command; 251 } 252 253 //------------------------------------------------------------------------------ 254 Culling(const RenderState & renderState_)255 RenderState::Culling::Culling( const RenderState& renderState_ ) 256 : isEnable( true ), 257 frontFace( FRONT_FACE_CCW ), 258 cullFace( CULL_FACE_BACK ), 259 m_RenderState( renderState_ ) 260 { 261 } 262 263 //------------------------------------------------------------------------------ 264 Blend(const RenderState & renderState_)265 RenderState::Blend::Blend( const RenderState& renderState_ ) 266 : isEnable( false ), 267 eqRgb ( PICA_DATA_BLEND_EQUATION_ADD ), 268 eqAlpha ( PICA_DATA_BLEND_EQUATION_ADD ), 269 srcRgb ( PICA_DATA_BLEND_FUNC_SRC_ALPHA ), 270 srcAlpha( PICA_DATA_BLEND_FUNC_SRC_ALPHA ), 271 dstRgb ( PICA_DATA_BLEND_FUNC_ONE_MINUS_SRC_ALPHA ), 272 dstAlpha( PICA_DATA_BLEND_FUNC_ONE_MINUS_SRC_ALPHA ), 273 colorR( 0xff), 274 colorG( 0xff), 275 colorB( 0xff), 276 colorA( 0xff), 277 m_RenderState( renderState_ ) 278 { 279 } 280 281 //------------------------------------------------------------------------------ 282 LogicOp(const RenderState & renderState_)283 RenderState::LogicOp::LogicOp( const RenderState& renderState_ ) 284 : isEnable( false ), 285 opCode( PICA_DATA_LOGIC_NOOP ), 286 m_RenderState( renderState_ ) 287 { 288 } 289 290 //------------------------------------------------------------------------------ 291 AlphaTest(const RenderState & renderState_)292 RenderState::AlphaTest::AlphaTest( const RenderState& renderState_ ) 293 : isEnable( false ), 294 refValue( 0 ), 295 func ( PICA_DATA_ALPHA_TEST_NEVER ), 296 m_RenderState( renderState_ ) 297 { 298 } 299 300 //------------------------------------------------------------------------------ 301 StencilTest(const RenderState & renderState_)302 RenderState::StencilTest::StencilTest( const RenderState& renderState_ ) 303 : isEnable ( false ), 304 isEnableWrite( false ), 305 func ( PICA_DATA_STENCIL_TEST_ALWAYS ), 306 ref ( 0 ), 307 mask ( 0xff ), 308 opFail ( PICA_DATA_STENCIL_OP_KEEP ), 309 opZFail ( PICA_DATA_STENCIL_OP_KEEP ), 310 opZPass ( PICA_DATA_STENCIL_OP_KEEP ), 311 m_RenderState ( renderState_ ) 312 { 313 } 314 315 //------------------------------------------------------------------------------ 316 DepthTest(const RenderState & renderState_)317 RenderState::DepthTest::DepthTest( const RenderState& renderState_ ) 318 : isEnable( true ), 319 isEnableWrite( true ), 320 func( PICA_DATA_DEPTH_TEST_LESS ), 321 m_RenderState( renderState_ ) 322 { 323 } 324 325 //------------------------------------------------------------------------------ 326 WBuffer(const RenderState & renderState_)327 RenderState::WBuffer::WBuffer( const RenderState& renderState_ ) 328 : wScale( 0.f ), 329 isEnablePolygonOffset( false ), 330 polygonOffsetUnit ( 0.f ), 331 depthRangeNear ( 0.0f ), 332 depthRangeFar ( 1.0f ), 333 depthRangeBit ( 24 ), 334 m_RenderState ( renderState_ ) 335 { 336 } 337 338 339 //------------------------------------------------------------------------------ 340 FBAccess(const RenderState & renderState_)341 RenderState::FBAccess::FBAccess( const RenderState& renderState_ ) 342 : m_RenderState( renderState_ ) 343 { 344 } 345 346 //------------------------------------------------------------------------------ 347 RenderState()348 RenderState::RenderState() : 349 blend ( *this ), 350 logicOp ( *this ), 351 alphaTest ( *this ), 352 stencilTest ( *this ), 353 colorMask ( COLOR_MASK_RGBA ), 354 depthTest ( *this ), 355 cullingTest ( *this ), 356 wBuffer ( *this ), 357 fbAccess ( *this ) 358 { 359 } 360 361 } // namespace CTR 362 } // namespace gr 363 } // namespace nn 364