PS2GL
OpenGL*-like API for the PS2
Loading...
Searching...
No Matches
renderermanager.cpp
1/* Copyright (C) 2000,2001,2002 Sony Computer Entertainment America
2
3 This file is subject to the terms and conditions of the GNU Lesser
4 General Public License Version 2.1. See the file "COPYING" in the
5 main directory of this archive for more details. */
6
7#include "ps2s/packet.h"
8
9#include "ps2gl/glcontext.h"
10#include "ps2gl/metrics.h"
11#include "ps2gl/renderermanager.h"
12
13#include "ps2gl/indexed_renderer.h"
14#include "ps2gl/linear_renderer.h"
15
16#include "vu1_mem_linear.h"
17#include "vu1renderers.h"
18
19using namespace RendererProps;
20
21/********************************************
22 * methods
23 */
24
25CRendererManager::CRendererManager(CGLContext& context)
26 : GLContext(context)
27 , RendererReqsHaveChanged(false)
28 , CurUserPrimReqs(0)
29 , CurUserPrimReqMask(~0)
30 , NumDefaultRenderers(0)
31 , NumUserRenderers(0)
32 , CurrentRenderer(NULL)
33 , NewRenderer(NULL)
34{
35 RendererRequirements.PrimType = 0;
36 RendererRequirements.Lighting = 0;
37 RendererRequirements.NumDirLights = 0;
38 RendererRequirements.NumPtLights = 0;
39 RendererRequirements.Texture = 0;
40 RendererRequirements.Specular = 0;
41 RendererRequirements.PerVtxMaterial = kNoMaterial;
42 RendererRequirements.Clipping = kClipped;
43 RendererRequirements.CullFace = 0;
44 RendererRequirements.TwoSidedLighting = 0;
45 RendererRequirements.ArrayAccess = 0;
46 RendererRequirements.UserProps = 0;
47
48 CRendererProps no_reqs;
49 no_reqs = (tU64)0;
50
51 // indexed array renderer
52 {
53 CRendererProps capabilities = {
54 PrimType : kPtsLinesStripsFans,
55 Lighting : 1,
56 NumDirLights : k3DirLights | k8DirLights,
57 NumPtLights : k1PtLight | k2PtLights | k8PtLights,
58 Texture : 1,
59 Specular : 1,
60 PerVtxMaterial : kNoMaterial,
61 Clipping : kNonClipped | kClipped,
62 CullFace : 1,
63 TwoSidedLighting : 0,
64 ArrayAccess : kIndexed
65 };
66
67 RegisterDefaultRenderer(new CIndexedRenderer(mVsmAddr(Indexed), mVsmSize(Indexed), capabilities, no_reqs, 3, 3,
68 "indexed"));
69 }
70
71 // fast, no lights renderer
72 {
73 CRendererProps capabilities = {
74 PrimType : kPtsLinesStripsFans,
75 Lighting : 0,
76 NumDirLights : k3DirLights,
77 NumPtLights : 0,
78 Texture : 1,
79 Specular : 0,
80 PerVtxMaterial : kNoMaterial,
81 Clipping : kNonClipped,
82 CullFace : 0,
83 TwoSidedLighting : 0,
84 ArrayAccess : kLinear
85 };
86
87 RegisterDefaultRenderer(new CLinearRenderer(mVsmAddr(FastNoLights), mVsmSize(FastNoLights), capabilities, no_reqs, 3, 3,
88 kInputStart, kInputBufSize - kInputStart,
89 "fast, no lights"));
90 }
91 // fast renderer
92 {
93 CRendererProps capabilities = {
94 PrimType : kPtsLinesStripsFans,
95 Lighting : 1,
96 NumDirLights : k3DirLights,
97 NumPtLights : 0,
98 Texture : 1,
99 Specular : 0,
100 PerVtxMaterial : kNoMaterial,
101 Clipping : kNonClipped,
102 CullFace : 0,
103 TwoSidedLighting : 0,
104 ArrayAccess : kLinear
105 };
106
107 RegisterDefaultRenderer(new CLinearRenderer(mVsmAddr(Fast), mVsmSize(Fast), capabilities, no_reqs, 3, 3,
108 kInputStart, kInputBufSize - kInputStart,
109 "fast"));
110 }
111
112 // SCEI renderer
113 {
114 CRendererProps capabilities = {
115 PrimType : kPtsLinesStripsFans,
116 Lighting : 1,
117 NumDirLights : k3DirLights,
118 NumPtLights : 0,
119 Texture : 1,
120 Specular : 0,
121 PerVtxMaterial : kNoMaterial,
122 Clipping : kClipped,
123 CullFace : 0,
124 TwoSidedLighting : 0,
125 ArrayAccess : kLinear
126 };
127
128 RegisterDefaultRenderer(new CLinearRenderer(mVsmAddr(SCEI), mVsmSize(SCEI), capabilities, no_reqs, 3, 3,
129 kInputStart, kInputBufSize - kInputStart,
130 "scei"));
131 }
132
133 // linear, no specular renderers
134
135 {
136 CRendererProps capabilities = {
137 PrimType : kPtsLinesStripsFans,
138 Lighting : 1,
139 NumDirLights : k3DirLights | k8DirLights,
140 NumPtLights : k1PtLight | k2PtLights | k8PtLights,
141 Texture : 1,
142 Specular : 0,
143 PerVtxMaterial : kNoMaterial,
144 Clipping : kNonClipped | kClipped,
145 CullFace : 1,
146 TwoSidedLighting : 0,
147 ArrayAccess : kLinear
148 };
149
150 RegisterDefaultRenderer(new CLinearRenderer(mVsmAddr(GeneralNoSpec), mVsmSize(GeneralNoSpec), capabilities, no_reqs, 3, 3,
151 kInputStart, kInputBufSize - kInputStart,
152 "linear, no specular"));
153 }
154 {
155 CRendererProps capabilities = {
156 PrimType : kTriangles,
157 Lighting : 1,
158 NumDirLights : k3DirLights | k8DirLights,
159 NumPtLights : k1PtLight | k2PtLights | k8PtLights,
160 Texture : 1,
161 Specular : 0,
162 PerVtxMaterial : kNoMaterial,
163 Clipping : kNonClipped | kClipped,
164 CullFace : 1,
165 TwoSidedLighting : 0,
166 ArrayAccess : kLinear
167 };
168
169 RegisterDefaultRenderer(new CLinearRenderer(mVsmAddr(GeneralNoSpecTri), mVsmSize(GeneralNoSpecTri), capabilities, no_reqs, 3, 3,
170 kInputStart, kInputBufSize - kInputStart,
171 "linear, tris, no specular"));
172 }
173 {
174 CRendererProps capabilities = {
175 PrimType : kQuads,
176 Lighting : 1,
177 NumDirLights : k3DirLights | k8DirLights,
178 NumPtLights : k1PtLight | k2PtLights | k8PtLights,
179 Texture : 1,
180 Specular : 0,
181 PerVtxMaterial : kNoMaterial,
182 Clipping : kNonClipped | kClipped,
183 CullFace : 1,
184 TwoSidedLighting : 0,
185 ArrayAccess : kLinear
186 };
187
188 RegisterDefaultRenderer(new CLinearRenderer(mVsmAddr(GeneralNoSpecQuad), mVsmSize(GeneralNoSpecQuad), capabilities, no_reqs, 3, 3,
189 kInputStart, kInputBufSize - kInputStart,
190 "linear, quads, no specular"));
191 }
192
193 // linear renderers
194
195 {
196 CRendererProps capabilities = {
197 PrimType : kPtsLinesStripsFans,
198 Lighting : 1,
199 NumDirLights : k3DirLights | k8DirLights,
200 NumPtLights : k1PtLight | k2PtLights | k8PtLights,
201 Texture : 1,
202 Specular : 1,
203 PerVtxMaterial : kNoMaterial,
204 Clipping : kNonClipped | kClipped,
205 CullFace : 1,
206 TwoSidedLighting : 0,
207 ArrayAccess : kLinear
208 };
209
210 RegisterDefaultRenderer(new CLinearRenderer(mVsmAddr(General), mVsmSize(General), capabilities, no_reqs, 3, 3,
211 kInputStart, kInputBufSize - kInputStart,
212 "linear"));
213 }
214 {
215 CRendererProps capabilities = {
216 PrimType : kQuads,
217 Lighting : 1,
218 NumDirLights : k3DirLights | k8DirLights,
219 NumPtLights : k1PtLight | k2PtLights | k8PtLights,
220 Texture : 1,
221 Specular : 1,
222 PerVtxMaterial : kNoMaterial,
223 Clipping : kNonClipped | kClipped,
224 CullFace : 1,
225 TwoSidedLighting : 0,
226 ArrayAccess : kLinear
227 };
228
229 RegisterDefaultRenderer(new CLinearRenderer(mVsmAddr(GeneralQuad), mVsmSize(GeneralQuad), capabilities, no_reqs, 3, 3,
230 kInputStart, kInputBufSize - kInputStart,
231 "linear, quads"));
232 }
233 {
234 CRendererProps capabilities = {
235 PrimType : kTriangles,
236 Lighting : 1,
237 NumDirLights : k3DirLights | k8DirLights,
238 NumPtLights : k1PtLight | k2PtLights | k8PtLights,
239 Texture : 1,
240 Specular : 1,
241 PerVtxMaterial : kNoMaterial,
242 Clipping : kNonClipped | kClipped,
243 CullFace : 1,
244 TwoSidedLighting : 0,
245 ArrayAccess : kLinear
246 };
247
248 RegisterDefaultRenderer(new CLinearRenderer(mVsmAddr(GeneralTri), mVsmSize(GeneralTri), capabilities, no_reqs, 3, 3,
249 kInputStart, kInputBufSize - kInputStart,
250 "linear, tris"));
251 }
252
253 // linear, per-vertex color renderers
254
255 {
256 CRendererProps capabilities = {
257 PrimType : kPtsLinesStripsFans,
258 Lighting : 1,
259 NumDirLights : k3DirLights | k8DirLights,
260 NumPtLights : k1PtLight | k2PtLights | k8PtLights,
261 Texture : 1,
262 Specular : 1,
263 PerVtxMaterial : kDiffuse,
264 Clipping : kNonClipped | kClipped,
265 CullFace : 1,
266 TwoSidedLighting : 0,
267 ArrayAccess : kLinear
268 };
269
270 RegisterDefaultRenderer(new CLinearRenderer(mVsmAddr(GeneralPVDiff), mVsmSize(GeneralPVDiff), capabilities, no_reqs, 4, 3,
271 kInputStart, kInputBufSize - kInputStart,
272 "linear, pvc"));
273 }
274 {
275 CRendererProps capabilities = {
276 PrimType : kTriangles,
277 Lighting : 1,
278 NumDirLights : k3DirLights | k8DirLights,
279 NumPtLights : k1PtLight | k2PtLights | k8PtLights,
280 Texture : 1,
281 Specular : 1,
282 PerVtxMaterial : kDiffuse,
283 Clipping : kNonClipped | kClipped,
284 CullFace : 1,
285 TwoSidedLighting : 0,
286 ArrayAccess : kLinear
287 };
288
289 RegisterDefaultRenderer(new CLinearRenderer(mVsmAddr(GeneralPVDiffTri), mVsmSize(GeneralPVDiffTri), capabilities, no_reqs, 4, 3,
290 kInputStart, kInputBufSize - kInputStart,
291 "linear, pvc, tris"));
292 }
293 {
294 CRendererProps capabilities = {
295 PrimType : kQuads,
296 Lighting : 1,
297 NumDirLights : k3DirLights | k8DirLights,
298 NumPtLights : k1PtLight | k2PtLights | k8PtLights,
299 Texture : 1,
300 Specular : 1,
301 PerVtxMaterial : kDiffuse,
302 Clipping : kNonClipped | kClipped,
303 CullFace : 1,
304 TwoSidedLighting : 0,
305 ArrayAccess : kLinear
306 };
307
308 RegisterDefaultRenderer(new CLinearRenderer(mVsmAddr(GeneralPVDiffQuad), mVsmSize(GeneralPVDiffQuad), capabilities, no_reqs, 4, 3,
309 kInputStart, kInputBufSize - kInputStart,
310 "linear, pvc, quads"));
311 }
312
313 // if we don't do this pglGetCurRendererName() will crash if called before rendering
314 // any geometry
315 CurrentRenderer = &DefaultRenderers[0];
316}
317
318void CRendererManager::RegisterDefaultRenderer(CRenderer* renderer)
319{
320 mErrorIf(NumDefaultRenderers == kMaxDefaultRenderers,
321 "Trying to register too many renderers; adjust the limit");
322
323 tRenderer newEntry = { renderer->GetCapabilities(), renderer->GetRequirements(), renderer };
324 DefaultRenderers[NumDefaultRenderers++] = newEntry;
325}
326
327void CRendererManager::RegisterUserRenderer(CRenderer* renderer)
328{
329 mErrorIf(renderer == NULL,
330 "Trying to register a null renderer is not playing fair...");
331
332 mErrorIf(NumUserRenderers == kMaxUserRenderers,
333 "Trying to register too many renderers; adjust the limit");
334
335 tRenderer newEntry = { renderer->GetCapabilities(), renderer->GetRequirements(), renderer };
336 UserRenderers[NumUserRenderers++] = newEntry;
337}
338
339// state updates
340
341void CRendererManager::EnableCustom(tU64 flag)
342{
343 tU64 newState = RendererRequirements;
344 newState |= flag;
345
346 if (newState != (tU64)RendererRequirements)
347 RendererReqsHaveChanged = true;
348
349 RendererRequirements = newState;
350}
351
352void CRendererManager::DisableCustom(tU64 flag)
353{
354 tU64 newState = RendererRequirements;
355 newState &= ~flag;
356
357 if (newState != (tU64)RendererRequirements)
358 RendererReqsHaveChanged = true;
359
360 RendererRequirements = newState;
361}
362
363void CRendererManager::NumLightsChanged(tLightType type, int num)
364{
365 CRendererProps newState = RendererRequirements;
366
367 switch (type) {
368 case kDirectional:
369 if (num == 0)
370 newState.NumDirLights = 0;
371 else if (0 < num && num <= 3)
372 newState.NumDirLights = k3DirLights; // in namespace??
373 else
374 newState.NumDirLights = k8DirLights;
375
376 if (RendererRequirements != newState) {
377 RendererRequirements = newState;
378 RendererReqsHaveChanged = true;
379 }
380 break;
381
382 case kPoint:
383 if (num == 0)
384 newState.NumPtLights = 0;
385 else if (num == 1)
386 newState.NumPtLights = k1PtLight;
387 else if (num == 2)
388 newState.NumPtLights = k2PtLights;
389 else
390 newState.NumPtLights = k8PtLights;
391
392 if (RendererRequirements != newState) {
393 RendererRequirements = newState;
394 RendererReqsHaveChanged = true;
395 }
396 break;
397
398 case kSpot:
399 break;
400 }
401}
402
403void CRendererManager::PrimChanged(unsigned int prim)
404{
405 // is this a user-defined prim type?
406 if (CGeomManager::IsUserPrimType(prim)) {
407 // user-defined
408
409 tU64 newState = RendererRequirements;
410
411 // clear the current user prim flags (if any)
412 newState &= ~CurUserPrimReqs;
413
414 // clear the user-prim-type flag (bit 31)
415 prim &= 0x7fffffff;
416
417 CurUserPrimReqs = CGeomManager::GetUserPrimRequirements(prim);
418 newState |= CurUserPrimReqs;
419
420 CurUserPrimReqMask = CGeomManager::GetUserPrimReqMask(prim);
421
422 if ((tU64)RendererRequirements != newState) {
423 RendererRequirements = newState;
424 RendererReqsHaveChanged = true;
425 }
426 } else {
427 // normal prim type
428
429 CRendererProps newState = RendererRequirements;
430
431 if (CurUserPrimReqs) {
432 RendererReqsHaveChanged = true;
433 // clear any requirements set by a user prim type
434 newState = (tU64)newState & ~CurUserPrimReqs;
435 CurUserPrimReqs = 0;
436 }
437
438 CurUserPrimReqMask = ~(tU32)0;
439
440 if (prim <= GL_LINE_STRIP)
441 newState.PrimType = kPtsLinesStripsFans;
442 else if (prim == GL_TRIANGLE_STRIP
443 || prim == GL_TRIANGLE_FAN
444 || prim == GL_POLYGON)
445 newState.PrimType = kPtsLinesStripsFans;
446 else if (prim == GL_QUAD_STRIP)
447 newState.PrimType = kPtsLinesStripsFans;
448 else if (prim == GL_TRIANGLES)
449 newState.PrimType = kTriangles;
450 else if (prim == GL_QUADS)
451 newState.PrimType = kQuads;
452 else {
453 mError("shouldn't get here");
454 }
455
456 if (RendererRequirements != newState) {
457 RendererRequirements = newState;
458 RendererReqsHaveChanged = true;
459 }
460 }
461}
462
463void CRendererManager::TexEnabledChanged(bool enabled)
464{
465 CRendererProps newState = RendererRequirements;
466
467 if (enabled)
468 newState.Texture = 1;
469 else
470 newState.Texture = 0;
471
472 if (RendererRequirements != newState) {
473 RendererRequirements = newState;
474 RendererReqsHaveChanged = true;
475 }
476}
477
478void CRendererManager::LightingEnabledChanged(bool enabled)
479{
480 CRendererProps newState = RendererRequirements;
481
482 if (enabled)
483 newState.Lighting = 1;
484 else
485 newState.Lighting = 0;
486
487 if (RendererRequirements != newState) {
488 RendererRequirements = newState;
489 RendererReqsHaveChanged = true;
490 }
491}
492
493void CRendererManager::SpecularEnabledChanged(bool enabled)
494{
495 CRendererProps newState = RendererRequirements;
496
497 if (enabled)
498 newState.Specular = 1;
499 else
500 newState.Specular = 0;
501
502 if (RendererRequirements != newState) {
503 RendererRequirements = newState;
504 RendererReqsHaveChanged = true;
505 }
506}
507
508void CRendererManager::PerVtxMaterialChanged(RendererProps::tPerVtxMaterial matType)
509{
510 if (RendererRequirements.PerVtxMaterial != (unsigned int)matType) {
511 RendererRequirements.PerVtxMaterial = matType;
512 RendererReqsHaveChanged = true;
513 }
514}
515
516void CRendererManager::ClippingEnabledChanged(bool enabled)
517{
518 tClipping clipping = (enabled) ? kClipped : kNonClipped;
519 if (RendererRequirements.Clipping != (unsigned int)clipping) {
520 RendererRequirements.Clipping = clipping;
521 RendererReqsHaveChanged = true;
522 }
523}
524
525void CRendererManager::CullFaceEnabledChanged(bool enabled)
526{
527 if (RendererRequirements.CullFace != enabled) {
528 RendererRequirements.CullFace = enabled;
529 RendererReqsHaveChanged = true;
530 }
531}
532
533void CRendererManager::ArrayAccessChanged(RendererProps::tArrayAccess accessType)
534{
535 if (RendererRequirements.ArrayAccess != (unsigned int)accessType) {
536 RendererRequirements.ArrayAccess = accessType;
537 RendererReqsHaveChanged = true;
538 }
539}
540
548{
549 bool rendererChanged = false;
550
551 if (RendererReqsHaveChanged) {
552 // do a little fixin' up..
553 CRendererProps rreqs = RendererRequirements;
554 if (!rreqs.Lighting) {
555 // don't care about these if there's no light
556 rreqs.Specular = 0;
557 rreqs.TwoSidedLighting = 0;
558 }
559
560 rreqs = (tU64)rreqs & CurUserPrimReqMask;
561
562 // first check the user renderers
563
564 int i;
565 bool userRendererFound = false;
566
567 for (i = 0; i < NumUserRenderers; i++)
568 if (rreqs == (rreqs & UserRenderers[i].capabilities)
569 && UserRenderers[i].requirements == (rreqs & UserRenderers[i].requirements))
570 break;
571
572 // did we find a user renderer?
573 if (i < NumUserRenderers) {
574 userRendererFound = true;
575
576 NewRenderer = &UserRenderers[i];
577
578 if (CurrentRenderer != &UserRenderers[i]) {
579 rendererChanged = true;
580 }
581 }
582
583 // now the default renderers
584
585 if (!userRendererFound) {
586 for (i = 0; i < NumDefaultRenderers; i++)
587 if (rreqs == (rreqs & DefaultRenderers[i].capabilities)
588 && DefaultRenderers[i].requirements == (rreqs & DefaultRenderers[i].requirements))
589 break;
590
591 mErrorIf(i == NumDefaultRenderers,
592 "Couldn't find a suitable renderer..\n"
593 "state reqs = 0x%08x 0x%08x, mask = %08x %08x\n",
594 (tU32)((tU64)rreqs >> 32),
595 (tU32)((tU64)rreqs),
596 (tU32)((tU64)CurUserPrimReqMask >> 32),
597 (tU32)((tU64)CurUserPrimReqMask));
598
599 NewRenderer = &DefaultRenderers[i];
600
601 if (CurrentRenderer != &DefaultRenderers[i]) {
602 // printf("vu1 renderer requirements are 0x%08x, renderer = 0x%08x i = %d\n",
603 // (unsigned int)RendererRequirements, (unsigned int)CurrentRenderer->capabilities, i);
604 rendererChanged = true;
605 }
606 }
607 }
608
609 RendererReqsHaveChanged = false;
610
611 return rendererChanged;
612}
613
614void CRendererManager::MakeNewRendererCurrent()
615{
616 mAssert(NewRenderer != NULL);
617 CurrentRenderer = NewRenderer;
618 NewRenderer = NULL;
619}
620
621void CRendererManager::LoadRenderer(CVifSCDmaPacket& packet)
622{
623 mAssert(CurrentRenderer != NULL);
624
625 mDebugPrint("Loading renderer: %s\n", CurrentRenderer->renderer->GetName());
626
627 CurrentRenderer->renderer->Load();
628
629 pglAddToMetric(kMetricsRendererUpload);
630}
631
632/********************************************
633 * ps2gl C api
634 */
635
693{
694 // does nothing now, but a begin/end pair could come in handy later
695 // if I add caches, hashes, etc..
696}
697
704void pglRegisterRenderer(void* renderer)
705{
706 CRenderer* newRenderer = reinterpret_cast<CRenderer*>(renderer);
707 pGLContext->GetImmGeomManager().GetRendererManager().RegisterUserRenderer(newRenderer);
708}
709
714{
715 // see comment in begin
716}
717
724const char*
726{
727 return pGLContext->GetImmGeomManager().GetRendererManager().GetCurRenderer().GetName();
728}
729
virtual void Load()=0
Load the renderer into vu0/vu1 memory.
virtual const char * GetName()=0
Return a pointer to the text name of this renderer.
void pglRegisterRenderer(void *renderer)
const char * pglGetCurRendererName()
void pglEndRendererDefs()
void pglBeginRendererDefs()