Avoid using an element buffer in more cases.

This commit is contained in:
Henrik Rydgard 2013-01-20 22:42:11 +01:00
parent d9c9a9102a
commit e15b580df6
3 changed files with 25 additions and 21 deletions

View file

@ -28,11 +28,6 @@ const u8 indexedPrimitiveType[7] = {
GE_PRIM_RECTANGLES,
};
enum {
SEEN_INDEX8 = 1 << 29,
SEEN_INDEX16 = 1 << 30
};
void IndexGenerator::Reset() {
prim_ = -1;
count_ = 0;
@ -190,7 +185,7 @@ void IndexGenerator::TranslateFan(int numVerts, const u8 *inds, int offset)
index_ += numVerts;
count_ += numTris * 3;
prim_ = GE_PRIM_TRIANGLES;
seenPrims_ |= (1 << GE_PRIM_TRIANGLE_STRIP) | SEEN_INDEX8;;
seenPrims_ |= (1 << GE_PRIM_TRIANGLE_FAN) | SEEN_INDEX8;
}
void IndexGenerator::TranslateList(int numVerts, const u16 *inds, int offset)
@ -323,7 +318,7 @@ void IndexGenerator::TranslateLineList(int numVerts, const u16 *inds, int offset
index_ += numVerts;
count_ += numLines * 2;
prim_ = GE_PRIM_LINES;
seenPrims_ |= 1 << GE_PRIM_LINES;
seenPrims_ |= (1 << GE_PRIM_LINES) | SEEN_INDEX16;
}
void IndexGenerator::TranslateLineStrip(int numVerts, const u16 *inds, int offset)
@ -337,7 +332,7 @@ void IndexGenerator::TranslateLineStrip(int numVerts, const u16 *inds, int offse
index_ += numVerts;
count_ += numLines * 2;
prim_ = GE_PRIM_LINES;
seenPrims_ |= 1 << GE_PRIM_LINE_STRIP;
seenPrims_ |= (1 << GE_PRIM_LINE_STRIP) | SEEN_INDEX16;
}
void IndexGenerator::TranslateRectangles(int numVerts, const u8 *inds, int offset)
@ -351,7 +346,7 @@ void IndexGenerator::TranslateRectangles(int numVerts, const u8 *inds, int offse
index_ += numVerts;
count_ += numRects * 2;
prim_ = GE_PRIM_RECTANGLES;
seenPrims_ |= 1 << GE_PRIM_RECTANGLES;
seenPrims_ |= (1 << GE_PRIM_RECTANGLES) | SEEN_INDEX8;
}
void IndexGenerator::TranslateRectangles(int numVerts, const u16 *inds, int offset)
@ -365,5 +360,5 @@ void IndexGenerator::TranslateRectangles(int numVerts, const u16 *inds, int offs
index_ += numVerts;
count_ += numRects * 2;
prim_ = GE_PRIM_RECTANGLES;
seenPrims_ |= 1 << GE_PRIM_RECTANGLES;
seenPrims_ |= (1 << GE_PRIM_RECTANGLES) | SEEN_INDEX16;
}

View file

@ -74,7 +74,16 @@ public:
seenPrims_ == (1 << GE_PRIM_POINTS);
}
bool SeenIndices() const {
return (seenPrims_ & (SEEN_INDEX8 | SEEN_INDEX16)) != 0;
}
private:
enum {
SEEN_INDEX8 = 1 << 16,
SEEN_INDEX16 = 1 << 17
};
u16 *indsBase_;
u16 *inds_;
int index_;

View file

@ -651,7 +651,7 @@ void TransformDrawEngine::SoftwareTransformAndDraw(
if (useVBO) {
// Attempt to orphan the buffer we used so the GPU can alloc a new one.
// glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(short) * numTrans, 0, GL_DYNAMIC_DRAW);
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
} else {
glDrawArrays(glprim[prim], 0, numTrans);
@ -659,7 +659,7 @@ void TransformDrawEngine::SoftwareTransformAndDraw(
if (useVBO) {
// Attempt to orphan the buffer we used so the GPU can alloc a new one.
// glBufferData(GL_ARRAY_BUFFER, vertexSize * numTrans, 0, GL_DYNAMIC_DRAW);
// glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
curVbo_++;
if (curVbo_ == NUM_VBOS)
curVbo_ = 0;
@ -696,7 +696,7 @@ void TransformDrawEngine::SubmitPrim(void *verts, void *inds, int prim, int vert
dc.verts = verts;
dc.inds = inds;
dc.vertType = vertType;
dc.indexType = forceIndexType == (-1 ? (vertType & GE_VTYPE_IDX_MASK) : forceIndexType) >> GE_VTYPE_IDX_SHIFT;
dc.indexType = ((forceIndexType == -1) ? (vertType & GE_VTYPE_IDX_MASK) : forceIndexType) >> GE_VTYPE_IDX_SHIFT;
dc.prim = prim;
dc.vertexCount = vertexCount;
if (inds) {
@ -875,6 +875,7 @@ void TransformDrawEngine::Flush() {
{
u32 newHash = ComputeHash();
vai->numDraws++;
// TODO: tweak
if (vai->numDraws > 100000) {
vai->status = VertexArrayInfo::VAI_RELIABLE;
}
@ -897,21 +898,19 @@ void TransformDrawEngine::Flush() {
DecodeVerts();
vai->numVerts = indexGen.VertexCount();
vai->prim = indexGen.Prim();
useElements = !indexGen.SeenOnlyPurePrims();
glGenBuffers(1, &vai->vbo);
// TODO: in some cases we can avoid creating an element buffer.
glBindBuffer(GL_ARRAY_BUFFER, vai->vbo);
glBufferData(GL_ARRAY_BUFFER, dec.GetDecVtxFmt().stride * indexGen.MaxIndex(), decoded, GL_STATIC_DRAW);
// If there's only been one primitive type, and it's either TRIANGLES, LINES or POINTS,
// there is no need for the index buffer we built. We can then use glDrawArrays instead
// for a very minor speed boost.
glBindBuffer(GL_ARRAY_BUFFER, vai->vbo);
glBufferData(GL_ARRAY_BUFFER, dec.GetDecVtxFmt().stride * indexGen.MaxIndex(), decoded, GL_STATIC_DRAW);
// GAH removing the "true" causes crashes and I don't understand why.
if (true || !indexGen.SeenOnlyPurePrims()) {
if (useElements) {
glGenBuffers(1, &vai->ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vai->ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(short) * indexGen.VertexCount(), (GLvoid *)decIndex, GL_STATIC_DRAW);
} else {
useElements = false;
vai->ebo = 0;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
@ -919,6 +918,7 @@ void TransformDrawEngine::Flush() {
glBindBuffer(GL_ARRAY_BUFFER, vai->vbo);
if (vai->ebo)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vai->ebo);
useElements = vai->ebo ? true : false;
}
vbo = vai->vbo;
ebo = vai->ebo;
@ -963,7 +963,7 @@ rotateVBO:
curVbo_ = 0;
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, dec.GetDecVtxFmt().stride * indexGen.MaxIndex(), decoded, GL_STREAM_DRAW);
if (!indexGen.SeenOnlyPurePrims()) {
if (useElements) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(short) * indexGen.VertexCount(), (GLvoid *)decIndex, GL_STREAM_DRAW);
}