00001
00002
00003 This file is subject to the terms and conditions of the GNU Lesser
00004 General Public License Version 2.1. See the file "COPYING" in the
00005 main directory of this archive for more details. */
00006
00007 #include "ps2s/packet.h"
00008
00009 #include "ps2gl/renderermanager.h"
00010 #include "ps2gl/glcontext.h"
00011 #include "ps2gl/metrics.h"
00012
00013 #include "ps2gl/linear_renderer.h"
00014 #include "ps2gl/indexed_renderer.h"
00015
00016 #include "vu1renderers.h"
00017 #include "vu1_mem_linear.h"
00018
00019 using namespace RendererProps;
00020
00021 extern "C" void vsmIndexed();
00022
00023
00024 * methods
00025 */
00026
00027 #ifdef PS2_LINUX
00028 # include <sys/mman.h>
00029 # define mVsmAddr(__sym) \
00030 (void*)(dmaableRenderers + (tU32)__sym - (tU32)vsmStart)
00031
00032
00033 extern int Ps2stuffDeviceFd;
00034 #else
00035 # define mVsmAddr(__sym) (void*)__sym
00036 #endif
00037
00038 CRendererManager::CRendererManager( CGLContext &context)
00039 : GLContext(context),
00040 RendererReqsHaveChanged(false),
00041 CurUserPrimReqs(0), CurUserPrimReqMask(~0),
00042 NumDefaultRenderers(0), NumUserRenderers(0),
00043 CurrentRenderer(NULL), NewRenderer(NULL)
00044 {
00045 RendererRequirements.PrimType = 0;
00046 RendererRequirements.Lighting = 0;
00047 RendererRequirements.NumDirLights = 0;
00048 RendererRequirements.NumPtLights = 0;
00049 RendererRequirements.Texture = 0;
00050 RendererRequirements.Specular = 0;
00051 RendererRequirements.PerVtxMaterial = kNoMaterial;
00052 RendererRequirements.Clipping = kClipped;
00053 RendererRequirements.CullFace = 0;
00054 RendererRequirements.TwoSidedLighting = 0;
00055 RendererRequirements.ArrayAccess = 0;
00056 RendererRequirements.UserProps = 0;
00057
00058 #ifdef PS2_LINUX
00059 tU32 dmaableRenderers = (tU32)mmap(0, (tU32)vsmEnd - (tU32)vsmStart,
00060 PROT_READ | PROT_WRITE,
00061 MAP_SHARED, Ps2stuffDeviceFd,
00062 1 );
00063 memcpy( (void*)dmaableRenderers, (void*)vsmStart, (tU32)vsmEnd - (tU32)vsmStart );
00064 #endif
00065
00066 CRendererProps no_reqs;
00067 no_reqs = (tU64)0;
00068
00069
00070 {
00071 CRendererProps capabilities =
00072 {
00073 PrimType: kPtsLinesStripsFans,
00074 Lighting: 1,
00075 NumDirLights: k3DirLights | k8DirLights,
00076 NumPtLights: k1PtLight | k2PtLights | k8PtLights,
00077 Texture: 1,
00078 Specular: 1,
00079 PerVtxMaterial: kNoMaterial,
00080 Clipping: kNonClipped | kClipped,
00081 CullFace: 1,
00082 TwoSidedLighting: 0,
00083 ArrayAccess: kIndexed
00084 };
00085
00086 RegisterDefaultRenderer( new CIndexedRenderer(mVsmAddr(vsmIndexed), capabilities, no_reqs, 3, 3,
00087 "indexed") );
00088 }
00089
00090
00091 {
00092 CRendererProps capabilities =
00093 {
00094 PrimType: kPtsLinesStripsFans,
00095 Lighting: 0,
00096 NumDirLights: k3DirLights,
00097 NumPtLights: 0,
00098 Texture: 1,
00099 Specular: 0,
00100 PerVtxMaterial: kNoMaterial,
00101 Clipping: kNonClipped,
00102 CullFace: 0,
00103 TwoSidedLighting: 0,
00104 ArrayAccess: kLinear
00105 };
00106
00107 RegisterDefaultRenderer( new CLinearRenderer(mVsmAddr(vsmFastNoLights), capabilities, no_reqs, 3, 3,
00108 kInputStart, kInputBufSize - kInputStart,
00109 "fast, no lights") );
00110 }
00111
00112 {
00113 CRendererProps capabilities =
00114 {
00115 PrimType: kPtsLinesStripsFans,
00116 Lighting: 1,
00117 NumDirLights: k3DirLights,
00118 NumPtLights: 0,
00119 Texture: 1,
00120 Specular: 0,
00121 PerVtxMaterial: kNoMaterial,
00122 Clipping: kNonClipped,
00123 CullFace: 0,
00124 TwoSidedLighting: 0,
00125 ArrayAccess: kLinear
00126 };
00127
00128 RegisterDefaultRenderer( new CLinearRenderer(mVsmAddr(vsmFast), capabilities, no_reqs, 3, 3,
00129 kInputStart, kInputBufSize - kInputStart,
00130 "fast") );
00131 }
00132
00133
00134 {
00135 CRendererProps capabilities =
00136 {
00137 PrimType: kPtsLinesStripsFans,
00138 Lighting: 1,
00139 NumDirLights: k3DirLights,
00140 NumPtLights: 0,
00141 Texture: 1,
00142 Specular: 0,
00143 PerVtxMaterial: kNoMaterial,
00144 Clipping: kClipped,
00145 CullFace: 0,
00146 TwoSidedLighting: 0,
00147 ArrayAccess: kLinear
00148 };
00149
00150 RegisterDefaultRenderer( new CLinearRenderer(mVsmAddr(vsmSCEI), capabilities, no_reqs, 3, 3,
00151 kInputStart, kInputBufSize - kInputStart,
00152 "scei") );
00153 }
00154
00155
00156
00157 {
00158 CRendererProps capabilities =
00159 {
00160 PrimType: kPtsLinesStripsFans,
00161 Lighting: 1,
00162 NumDirLights: k3DirLights | k8DirLights,
00163 NumPtLights: k1PtLight | k2PtLights | k8PtLights,
00164 Texture: 1,
00165 Specular: 0,
00166 PerVtxMaterial: kNoMaterial,
00167 Clipping: kNonClipped | kClipped,
00168 CullFace: 1,
00169 TwoSidedLighting: 0,
00170 ArrayAccess: kLinear
00171 };
00172
00173 RegisterDefaultRenderer( new CLinearRenderer(mVsmAddr(vsmGeneralNoSpec), capabilities, no_reqs, 3, 3,
00174 kInputStart, kInputBufSize - kInputStart,
00175 "linear, no specular") );
00176 }
00177 {
00178 CRendererProps capabilities =
00179 {
00180 PrimType: kTriangles,
00181 Lighting: 1,
00182 NumDirLights: k3DirLights | k8DirLights,
00183 NumPtLights: k1PtLight | k2PtLights | k8PtLights,
00184 Texture: 1,
00185 Specular: 0,
00186 PerVtxMaterial: kNoMaterial,
00187 Clipping: kNonClipped | kClipped,
00188 CullFace: 1,
00189 TwoSidedLighting: 0,
00190 ArrayAccess: kLinear
00191 };
00192
00193 RegisterDefaultRenderer( new CLinearRenderer(mVsmAddr(vsmGeneralNoSpecTri), capabilities, no_reqs, 3, 3,
00194 kInputStart, kInputBufSize - kInputStart,
00195 "linear, tris, no specular") );
00196 }
00197 {
00198 CRendererProps capabilities =
00199 {
00200 PrimType: kQuads,
00201 Lighting: 1,
00202 NumDirLights: k3DirLights | k8DirLights,
00203 NumPtLights: k1PtLight | k2PtLights | k8PtLights,
00204 Texture: 1,
00205 Specular: 0,
00206 PerVtxMaterial: kNoMaterial,
00207 Clipping: kNonClipped | kClipped,
00208 CullFace: 1,
00209 TwoSidedLighting: 0,
00210 ArrayAccess: kLinear
00211 };
00212
00213 RegisterDefaultRenderer( new CLinearRenderer(mVsmAddr(vsmGeneralNoSpecQuad), capabilities, no_reqs, 3, 3,
00214 kInputStart, kInputBufSize - kInputStart,
00215 "linear, quads, no specular") );
00216 }
00217
00218
00219
00220 {
00221 CRendererProps capabilities =
00222 {
00223 PrimType: kPtsLinesStripsFans,
00224 Lighting: 1,
00225 NumDirLights: k3DirLights | k8DirLights,
00226 NumPtLights: k1PtLight | k2PtLights | k8PtLights,
00227 Texture: 1,
00228 Specular: 1,
00229 PerVtxMaterial: kNoMaterial,
00230 Clipping: kNonClipped | kClipped,
00231 CullFace: 1,
00232 TwoSidedLighting: 0,
00233 ArrayAccess: kLinear
00234 };
00235
00236 RegisterDefaultRenderer( new CLinearRenderer(mVsmAddr(vsmGeneral), capabilities, no_reqs, 3, 3,
00237 kInputStart, kInputBufSize - kInputStart,
00238 "linear") );
00239 }
00240 {
00241 CRendererProps capabilities =
00242 {
00243 PrimType: kQuads,
00244 Lighting: 1,
00245 NumDirLights: k3DirLights | k8DirLights,
00246 NumPtLights: k1PtLight | k2PtLights | k8PtLights,
00247 Texture: 1,
00248 Specular: 1,
00249 PerVtxMaterial: kNoMaterial,
00250 Clipping: kNonClipped | kClipped,
00251 CullFace: 1,
00252 TwoSidedLighting: 0,
00253 ArrayAccess: kLinear
00254 };
00255
00256 RegisterDefaultRenderer( new CLinearRenderer(mVsmAddr(vsmGeneralQuad), capabilities, no_reqs, 3, 3,
00257 kInputStart, kInputBufSize - kInputStart,
00258 "linear, quads") );
00259 }
00260 {
00261 CRendererProps capabilities =
00262 {
00263 PrimType: kTriangles,
00264 Lighting: 1,
00265 NumDirLights: k3DirLights | k8DirLights,
00266 NumPtLights: k1PtLight | k2PtLights | k8PtLights,
00267 Texture: 1,
00268 Specular: 1,
00269 PerVtxMaterial: kNoMaterial,
00270 Clipping: kNonClipped | kClipped,
00271 CullFace: 1,
00272 TwoSidedLighting: 0,
00273 ArrayAccess: kLinear
00274 };
00275
00276 RegisterDefaultRenderer( new CLinearRenderer(mVsmAddr(vsmGeneralTri), capabilities, no_reqs, 3, 3,
00277 kInputStart, kInputBufSize - kInputStart,
00278 "linear, tris") );
00279 }
00280
00281
00282
00283 {
00284 CRendererProps capabilities =
00285 {
00286 PrimType: kPtsLinesStripsFans,
00287 Lighting: 1,
00288 NumDirLights: k3DirLights | k8DirLights,
00289 NumPtLights: k1PtLight | k2PtLights | k8PtLights,
00290 Texture: 1,
00291 Specular: 1,
00292 PerVtxMaterial: kDiffuse,
00293 Clipping: kNonClipped | kClipped,
00294 CullFace: 1,
00295 TwoSidedLighting: 0,
00296 ArrayAccess: kLinear
00297 };
00298
00299 RegisterDefaultRenderer( new CLinearRenderer(mVsmAddr(vsmGeneralPVDiff), capabilities, no_reqs, 4, 3,
00300 kInputStart, kInputBufSize - kInputStart,
00301 "linear, pvc") );
00302 }
00303 {
00304 CRendererProps capabilities =
00305 {
00306 PrimType: kTriangles,
00307 Lighting: 1,
00308 NumDirLights: k3DirLights | k8DirLights,
00309 NumPtLights: k1PtLight | k2PtLights | k8PtLights,
00310 Texture: 1,
00311 Specular: 1,
00312 PerVtxMaterial: kDiffuse,
00313 Clipping: kNonClipped | kClipped,
00314 CullFace: 1,
00315 TwoSidedLighting: 0,
00316 ArrayAccess: kLinear
00317 };
00318
00319 RegisterDefaultRenderer( new CLinearRenderer(mVsmAddr(vsmGeneralPVDiffTri), capabilities, no_reqs, 4, 3,
00320 kInputStart, kInputBufSize - kInputStart,
00321 "linear, pvc, tris") );
00322 }
00323 {
00324 CRendererProps capabilities =
00325 {
00326 PrimType: kQuads,
00327 Lighting: 1,
00328 NumDirLights: k3DirLights | k8DirLights,
00329 NumPtLights: k1PtLight | k2PtLights | k8PtLights,
00330 Texture: 1,
00331 Specular: 1,
00332 PerVtxMaterial: kDiffuse,
00333 Clipping: kNonClipped | kClipped,
00334 CullFace: 1,
00335 TwoSidedLighting: 0,
00336 ArrayAccess: kLinear
00337 };
00338
00339 RegisterDefaultRenderer( new CLinearRenderer(mVsmAddr(vsmGeneralPVDiffQuad), capabilities, no_reqs, 4, 3,
00340 kInputStart, kInputBufSize - kInputStart,
00341 "linear, pvc, quads") );
00342 }
00343
00344
00345
00346 CurrentRenderer = &DefaultRenderers[0];
00347 }
00348
00349 void
00350 CRendererManager::RegisterDefaultRenderer( CRenderer *renderer )
00351 {
00352 mErrorIf( NumDefaultRenderers == kMaxDefaultRenderers,
00353 "Trying to register too many renderers; adjust the limit" );
00354
00355 tRenderer newEntry = { renderer->GetCapabilities(), renderer->GetRequirements(), renderer };
00356 DefaultRenderers[NumDefaultRenderers++] = newEntry;
00357 }
00358
00359 void
00360 CRendererManager::RegisterUserRenderer( CRenderer *renderer )
00361 {
00362 mErrorIf( renderer == NULL,
00363 "Trying to register a null renderer is not playing fair..." );
00364
00365 mErrorIf( NumUserRenderers == kMaxUserRenderers,
00366 "Trying to register too many renderers; adjust the limit" );
00367
00368 tRenderer newEntry = { renderer->GetCapabilities(), renderer->GetRequirements(), renderer };
00369 UserRenderers[NumUserRenderers++] = newEntry;
00370 }
00371
00372
00373
00374 void
00375 CRendererManager::EnableCustom( tU64 flag )
00376 {
00377 tU64 newState = RendererRequirements;
00378 newState |= flag;
00379
00380 if ( newState != (tU64)RendererRequirements )
00381 RendererReqsHaveChanged = true;
00382
00383 RendererRequirements = newState;
00384 }
00385
00386 void
00387 CRendererManager::DisableCustom( tU64 flag )
00388 {
00389 tU64 newState = RendererRequirements;
00390 newState &= ~flag;
00391
00392 if ( newState != (tU64)RendererRequirements )
00393 RendererReqsHaveChanged = true;
00394
00395 RendererRequirements = newState;
00396 }
00397
00398 void
00399 CRendererManager::NumLightsChanged( tLightType type, int num )
00400 {
00401 CRendererProps newState = RendererRequirements;
00402
00403 switch (type) {
00404 case kDirectional:
00405 if ( num == 0 )
00406 newState.NumDirLights = 0;
00407 else if (0 < num && num <= 3)
00408 newState.NumDirLights = k3DirLights;
00409 else
00410 newState.NumDirLights = k8DirLights;
00411
00412 if ( RendererRequirements != newState ) {
00413 RendererRequirements = newState;
00414 RendererReqsHaveChanged = true;
00415 }
00416 break;
00417
00418 case kPoint:
00419 if (num == 0)
00420 newState.NumPtLights = 0;
00421 else if (num == 1)
00422 newState.NumPtLights = k1PtLight;
00423 else if (num == 2)
00424 newState.NumPtLights = k2PtLights;
00425 else
00426 newState.NumPtLights = k8PtLights;
00427
00428 if ( RendererRequirements != newState ) {
00429 RendererRequirements = newState;
00430 RendererReqsHaveChanged = true;
00431 }
00432 break;
00433
00434 case kSpot:
00435 break;
00436 }
00437 }
00438
00439 void
00440 CRendererManager::PrimChanged( unsigned int prim )
00441 {
00442
00443 if ( CGeomManager::IsUserPrimType(prim) ) {
00444
00445
00446 tU64 newState = RendererRequirements;
00447
00448
00449 newState &= ~CurUserPrimReqs;
00450
00451
00452 prim &= 0x7fffffff;
00453
00454 CurUserPrimReqs = CGeomManager::GetUserPrimRequirements(prim);
00455 newState |= CurUserPrimReqs;
00456
00457 CurUserPrimReqMask = CGeomManager::GetUserPrimReqMask(prim);
00458
00459 if ( (tU64)RendererRequirements != newState ) {
00460 RendererRequirements = newState;
00461 RendererReqsHaveChanged = true;
00462 }
00463 }
00464 else {
00465
00466
00467 CRendererProps newState = RendererRequirements;
00468
00469 if ( CurUserPrimReqs ) {
00470 RendererReqsHaveChanged = true;
00471
00472 newState = (tU64)newState & ~CurUserPrimReqs;
00473 CurUserPrimReqs = 0;
00474 }
00475
00476 CurUserPrimReqMask = ~(tU32)0;
00477
00478 if (prim <= GL_LINE_STRIP)
00479 newState.PrimType = kPtsLinesStripsFans;
00480 else if (prim == GL_TRIANGLE_STRIP
00481 || prim == GL_TRIANGLE_FAN
00482 || prim == GL_POLYGON)
00483 newState.PrimType = kPtsLinesStripsFans;
00484 else if (prim == GL_QUAD_STRIP)
00485 newState.PrimType = kPtsLinesStripsFans;
00486 else if (prim == GL_TRIANGLES)
00487 newState.PrimType = kTriangles;
00488 else if (prim == GL_QUADS)
00489 newState.PrimType = kQuads;
00490 else {
00491 mError("shouldn't get here");
00492 }
00493
00494 if ( RendererRequirements != newState ) {
00495 RendererRequirements = newState;
00496 RendererReqsHaveChanged = true;
00497 }
00498 }
00499 }
00500
00501 void
00502 CRendererManager::TexEnabledChanged( bool enabled )
00503 {
00504 CRendererProps newState = RendererRequirements;
00505
00506 if ( enabled ) newState.Texture = 1;
00507 else newState.Texture = 0;
00508
00509 if ( RendererRequirements != newState ) {
00510 RendererRequirements = newState;
00511 RendererReqsHaveChanged = true;
00512 }
00513 }
00514
00515 void
00516 CRendererManager::LightingEnabledChanged( bool enabled )
00517 {
00518 CRendererProps newState = RendererRequirements;
00519
00520 if (enabled) newState.Lighting = 1;
00521 else newState.Lighting = 0;
00522
00523 if (RendererRequirements != newState) {
00524 RendererRequirements = newState;
00525 RendererReqsHaveChanged = true;
00526 }
00527 }
00528
00529 void
00530 CRendererManager::SpecularEnabledChanged( bool enabled )
00531 {
00532 CRendererProps newState = RendererRequirements;
00533
00534 if (enabled) newState.Specular = 1;
00535 else newState.Specular = 0;
00536
00537 if (RendererRequirements != newState) {
00538 RendererRequirements = newState;
00539 RendererReqsHaveChanged = true;
00540 }
00541 }
00542
00543 void
00544 CRendererManager::PerVtxMaterialChanged( RendererProps::tPerVtxMaterial matType )
00545 {
00546 if ( RendererRequirements.PerVtxMaterial != (unsigned int)matType ) {
00547 RendererRequirements.PerVtxMaterial = matType;
00548 RendererReqsHaveChanged = true;
00549 }
00550 }
00551
00552 void
00553 CRendererManager::ClippingEnabledChanged( bool enabled )
00554 {
00555 tClipping clipping = (enabled) ? kClipped : kNonClipped;
00556 if ( RendererRequirements.Clipping != (unsigned int)clipping ) {
00557 RendererRequirements.Clipping = clipping;
00558 RendererReqsHaveChanged = true;
00559 }
00560 }
00561
00562 void
00563 CRendererManager::CullFaceEnabledChanged( bool enabled )
00564 {
00565 if ( RendererRequirements.CullFace != enabled ) {
00566 RendererRequirements.CullFace = enabled;
00567 RendererReqsHaveChanged = true;
00568 }
00569 }
00570
00571 void
00572 CRendererManager::ArrayAccessChanged( RendererProps::tArrayAccess accessType )
00573 {
00574 if ( RendererRequirements.ArrayAccess != (unsigned int)accessType ) {
00575 RendererRequirements.ArrayAccess = accessType;
00576 RendererReqsHaveChanged = true;
00577 }
00578 }
00579
00586 bool
00587 CRendererManager::UpdateNewRenderer()
00588 {
00589 bool rendererChanged = false;
00590
00591 if ( RendererReqsHaveChanged ) {
00592
00593 CRendererProps rreqs = RendererRequirements;
00594 if ( ! rreqs.Lighting ) {
00595
00596 rreqs.Specular = 0;
00597 rreqs.TwoSidedLighting = 0;
00598 }
00599
00600 rreqs = (tU64)rreqs & CurUserPrimReqMask;
00601
00602
00603
00604 int i;
00605 bool userRendererFound = false;
00606
00607 for ( i = 0; i < NumUserRenderers; i++ )
00608 if ( rreqs == (rreqs & UserRenderers[i].capabilities)
00609 && UserRenderers[i].requirements == (rreqs & UserRenderers[i].requirements) )
00610 break;
00611
00612
00613 if ( i < NumUserRenderers ) {
00614 userRendererFound = true;
00615
00616 NewRenderer = &UserRenderers[i];
00617
00618 if (CurrentRenderer != &UserRenderers[i]) {
00619 rendererChanged = true;
00620 }
00621 }
00622
00623
00624
00625 if ( ! userRendererFound ) {
00626 for ( i = 0; i < NumDefaultRenderers; i++ )
00627 if ( rreqs == (rreqs & DefaultRenderers[i].capabilities)
00628 && DefaultRenderers[i].requirements == (rreqs & DefaultRenderers[i].requirements) )
00629 break;
00630
00631 mErrorIf( i == NumDefaultRenderers,
00632 "Couldn't find a suitable renderer..\n"
00633 "state reqs = 0x%08x 0x%08x, mask = %08x %08x\n",
00634 (tU32)((tU64)rreqs >> 32),
00635 (tU32)((tU64)rreqs),
00636 (tU32)((tU64)CurUserPrimReqMask >> 32),
00637 (tU32)((tU64)CurUserPrimReqMask)
00638 );
00639
00640 NewRenderer = &DefaultRenderers[i];
00641
00642 if (CurrentRenderer != &DefaultRenderers[i]) {
00643
00644
00645 rendererChanged = true;
00646 }
00647 }
00648 }
00649
00650 RendererReqsHaveChanged = false;
00651
00652 return rendererChanged;
00653 }
00654
00655 void
00656 CRendererManager::MakeNewRendererCurrent()
00657 {
00658 mAssert( NewRenderer != NULL );
00659 CurrentRenderer = NewRenderer;
00660 NewRenderer = NULL;
00661 }
00662
00663 void
00664 CRendererManager::LoadRenderer( CVifSCDmaPacket &packet )
00665 {
00666 mAssert( CurrentRenderer != NULL );
00667
00668
00669
00670 CurrentRenderer->renderer->Load();
00671
00672 pglAddToMetric(kMetricsRendererUpload);
00673 }
00674
00675
00676 * ps2gl C api
00677 */
00678
00735 void
00736 pglBeginRendererDefs()
00737 {
00738
00739
00740 }
00741
00748 void
00749 pglRegisterRenderer( void *renderer )
00750 {
00751 CRenderer *newRenderer = reinterpret_cast<CRenderer*>(renderer);
00752 pGLContext->GetImmGeomManager().GetRendererManager().RegisterUserRenderer( newRenderer );
00753 }
00754
00758 void
00759 pglEndRendererDefs()
00760 {
00761
00762 }
00763
00770 const char*
00771 pglGetCurRendererName()
00772 {
00773 return pGLContext->GetImmGeomManager().GetRendererManager().GetCurRenderer().GetName();
00774 }
00775