1 // Copyright (c) 2012- PPSSPP Project.
2 
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0 or later versions.
6 
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 // GNU General Public License 2.0 for more details.
11 
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
14 
15 // Official git repository and contact information can be found at
16 // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17 
18 
19 #pragma once
20 
21 #include "Common/CommonTypes.h"
22 #include "Common/Swap.h"
23 #include "GPU/ge_constants.h"
24 
25 class IndexGenerator {
26 public:
27 	void Setup(u16 *indexptr);
Reset()28 	void Reset() {
29 		prim_ = GE_PRIM_INVALID;
30 		count_ = 0;
31 		index_ = 0;
32 		seenPrims_ = 0;
33 		pureCount_ = 0;
34 		this->inds_ = indsBase_;
35 	}
36 
PrimCompatible(int prim1,int prim2)37 	bool PrimCompatible(int prim1, int prim2) {
38 		if (prim1 == GE_PRIM_INVALID || prim2 == GE_PRIM_KEEP_PREVIOUS)
39 			return true;
40 		return indexedPrimitiveType[prim1] == indexedPrimitiveType[prim2];
41 	}
42 
PrimCompatible(int prim)43 	bool PrimCompatible(int prim) const {
44 		if (prim_ == GE_PRIM_INVALID || prim == GE_PRIM_KEEP_PREVIOUS)
45 			return true;
46 		return indexedPrimitiveType[prim] == prim_;
47 	}
48 
Prim()49 	GEPrimitiveType Prim() const { return prim_; }
50 
51 	void AddPrim(int prim, int vertexCount, bool clockwise);
52 	void TranslatePrim(int prim, int numInds, const u8 *inds, int indexOffset, bool clockwise);
53 	void TranslatePrim(int prim, int numInds, const u16_le *inds, int indexOffset, bool clockwise);
54 	void TranslatePrim(int prim, int numInds, const u32_le *inds, int indexOffset, bool clockwise);
55 
Advance(int numVerts)56 	void Advance(int numVerts) {
57 		index_ += numVerts;
58 	}
59 
SetIndex(int ind)60 	void SetIndex(int ind) { index_ = ind; }
MaxIndex()61 	int MaxIndex() const { return index_; }  // Really NextIndex rather than MaxIndex, it's one more than the highest index generated
VertexCount()62 	int VertexCount() const { return count_; }
Empty()63 	bool Empty() const { return index_ == 0; }
SeenPrims()64 	int SeenPrims() const { return seenPrims_; }
PureCount()65 	int PureCount() const { return pureCount_; }
SeenOnlyPurePrims()66 	bool SeenOnlyPurePrims() const {
67 		return seenPrims_ == (1 << GE_PRIM_TRIANGLES) ||
68 			seenPrims_ == (1 << GE_PRIM_LINES) ||
69 			seenPrims_ == (1 << GE_PRIM_POINTS) ||
70 			seenPrims_ == (1 << GE_PRIM_TRIANGLE_STRIP);
71 	}
72 
73 private:
74 	// Points (why index these? code simplicity)
75 	void AddPoints(int numVerts);
76 	// Triangles
77 	void AddList(int numVerts, bool clockwise);
78 	void AddStrip(int numVerts, bool clockwise);
79 	void AddFan(int numVerts, bool clockwise);
80 	// Lines
81 	void AddLineList(int numVerts);
82 	void AddLineStrip(int numVerts);
83 	// Rectangles
84 	void AddRectangles(int numVerts);
85 
86 	// These translate already indexed lists
87 	template <class ITypeLE, int flag>
88 	void TranslatePoints(int numVerts, const ITypeLE *inds, int indexOffset);
89 	template <class ITypeLE, int flag>
90 	void TranslateList(int numVerts, const ITypeLE *inds, int indexOffset, bool clockwise);
91 	template <class ITypeLE, int flag>
92 	inline void TranslateLineList(int numVerts, const ITypeLE *inds, int indexOffset);
93 	template <class ITypeLE, int flag>
94 	inline void TranslateLineStrip(int numVerts, const ITypeLE *inds, int indexOffset);
95 
96 	template <class ITypeLE, int flag>
97 	void TranslateStrip(int numVerts, const ITypeLE *inds, int indexOffset, bool clockwise);
98 	template <class ITypeLE, int flag>
99 	void TranslateFan(int numVerts, const ITypeLE *inds, int indexOffset, bool clockwise);
100 
101 	template <class ITypeLE, int flag>
102 	inline void TranslateRectangles(int numVerts, const ITypeLE *inds, int indexOffset);
103 
104 	enum {
105 		SEEN_INDEX8 = 1 << 16,
106 		SEEN_INDEX16 = 1 << 17,
107 		SEEN_INDEX32 = 1 << 18,
108 	};
109 
110 	u16 *indsBase_;
111 	u16 *inds_;
112 	int index_;
113 	int count_;
114 	int pureCount_;
115 	GEPrimitiveType prim_;
116 	int seenPrims_;
117 
118 	static const u8 indexedPrimitiveType[7];
119 };
120 
121