mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Merge pull request #22397 from hrydgard/point-batching
DrawEngine: Don't drop large batches of points, lines and rectangles
This commit is contained in:
4 files changed
+43
-2
No files matched your search
@@ -732,6 +732,17 @@ int DrawEngineCommon::ComputeNumVertsToDecode() const {
|
||||
|
||||
|
||||
|
||||
// How many vertices software transform turns a prim into, for the prims it expands to quads.
|
||||
static int ExpandedVertexCount(GEPrimitiveType prim, int vertexCount) {
|
||||
switch (prim) {
|
||||
case GE_PRIM_POINTS: return vertexCount * 4;
|
||||
case GE_PRIM_LINES: return (vertexCount / 2) * 4;
|
||||
case GE_PRIM_LINE_STRIP: return vertexCount > 1 ? (vertexCount - 1) * 4 : 0;
|
||||
case GE_PRIM_RECTANGLES: return (vertexCount / 2) * 4;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Takes a list of consecutive PRIM opcodes, and extends the current draw call to include them.
|
||||
// This is just a performance optimization. NOTE: This isn't compatible with really accurate culling,
|
||||
// unless we refactor things a bit.
|
||||
@@ -762,9 +773,11 @@ int DrawEngineCommon::ExtendNonIndexedPrim(const uint32_t *cmd, const uint32_t *
|
||||
if (IsTrianglePrim(newPrim) != isTriangle)
|
||||
break;
|
||||
int vertexCount = data & 0xFFFF;
|
||||
if (numDrawInds >= MAX_DEFERRED_DRAW_INDS || vertexCountInDrawCalls_ + offset + vertexCount > VERTEX_BUFFER_MAX || numVertsToDecode_ + (offset - dv.vertexCount) + vertexCount > VERTEX_BUFFER_MAX) {
|
||||
const int expanded = ExpandedVertexCount(newPrim, vertexCount);
|
||||
if (numDrawInds >= MAX_DEFERRED_DRAW_INDS || vertexCountInDrawCalls_ + offset + vertexCount > VERTEX_BUFFER_MAX || numVertsToDecode_ + (offset - dv.vertexCount) + vertexCount > VERTEX_BUFFER_MAX || expandedVertsInDrawCalls_ + expanded > VERTEX_BUFFER_MAX) {
|
||||
break;
|
||||
}
|
||||
expandedVertsInDrawCalls_ += expanded;
|
||||
DeferredInds &di = drawInds_[numDrawInds++];
|
||||
di.indexType = 0;
|
||||
di.prim = newPrim;
|
||||
@@ -809,6 +822,27 @@ void DrawEngineCommon::SkipPrim(GEPrimitiveType prim, int vertexCount, const Ver
|
||||
|
||||
// vertTypeID is the vertex type but with the UVGen mode smashed into the top bits.
|
||||
bool DrawEngineCommon::SubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, const VertexDecoder *dec, u32 vertTypeID, bool clockwise, int *bytesRead, ClipInfoFlags clipInfoFlags) {
|
||||
const GEPrimitiveType realPrim = prim != GE_PRIM_KEEP_PREVIOUS ? prim : (prevPrim_ == GE_PRIM_INVALID ? GE_PRIM_POINTS : prevPrim_);
|
||||
const int expanded = ExpandedVertexCount(realPrim, vertexCount);
|
||||
if (expanded > VERTEX_BUFFER_MAX) {
|
||||
// Software transform can't expand this many in one draw, so submit it in parts. Points, lines
|
||||
// and rectangles are independent of each other; consecutive parts of a line strip share a vertex.
|
||||
const bool strip = realPrim == GE_PRIM_LINE_STRIP;
|
||||
const int partSize = (realPrim == GE_PRIM_POINTS || strip) ? VERTEX_BUFFER_MAX / 4 : VERTEX_BUFFER_MAX / 2;
|
||||
static const int indexSizes[4] = { 0, 1, 2, 4 };
|
||||
const int indexSize = indexSizes[(vertTypeID & GE_VTYPE_IDX_MASK) >> GE_VTYPE_IDX_SHIFT];
|
||||
bool any = false;
|
||||
for (int start = 0; start < vertexCount - (strip ? 1 : 0); start += partSize) {
|
||||
const int count = std::min(partSize + (strip ? 1 : 0), vertexCount - start);
|
||||
const void *partVerts = inds ? verts : (const void *)((const u8 *)verts + start * dec->VertexSize());
|
||||
const void *partInds = inds ? (const void *)((const u8 *)inds + start * indexSize) : nullptr;
|
||||
int partBytesRead = 0;
|
||||
any = SubmitPrim(partVerts, partInds, realPrim, count, dec, vertTypeID, clockwise, &partBytesRead, clipInfoFlags) || any;
|
||||
}
|
||||
*bytesRead = vertexCount * dec->VertexSize();
|
||||
return any;
|
||||
}
|
||||
|
||||
// The index count doesn't bound how many vertices DecodeVerts will produce (the index range can be
|
||||
// sparse), so track that separately, as the growth of the range to decode.
|
||||
u16 lowerBound = 0;
|
||||
@@ -823,7 +857,7 @@ bool DrawEngineCommon::SubmitPrim(const void *verts, const void *inds, GEPrimiti
|
||||
}
|
||||
}
|
||||
|
||||
if (!indexGen.PrimCompatible(prevPrim_, prim) || numDrawVerts_ >= MAX_DEFERRED_DRAW_VERTS || numDrawInds_ >= MAX_DEFERRED_DRAW_INDS || vertexCountInDrawCalls_ + vertexCount > VERTEX_BUFFER_MAX || numVertsToDecode_ + decodeGrowth > VERTEX_BUFFER_MAX) {
|
||||
if (!indexGen.PrimCompatible(prevPrim_, prim) || numDrawVerts_ >= MAX_DEFERRED_DRAW_VERTS || numDrawInds_ >= MAX_DEFERRED_DRAW_INDS || vertexCountInDrawCalls_ + vertexCount > VERTEX_BUFFER_MAX || numVertsToDecode_ + decodeGrowth > VERTEX_BUFFER_MAX || expandedVertsInDrawCalls_ + expanded > VERTEX_BUFFER_MAX) {
|
||||
Flush();
|
||||
}
|
||||
|
||||
@@ -923,6 +957,7 @@ bool DrawEngineCommon::SubmitPrim(const void *verts, const void *inds, GEPrimiti
|
||||
}
|
||||
|
||||
vertexCountInDrawCalls_ += vertexCount;
|
||||
expandedVertsInDrawCalls_ += ExpandedVertexCount(prim, vertexCount);
|
||||
seenPrims_ |= (1 << prim);
|
||||
|
||||
if (prim == GE_PRIM_RECTANGLES && (gstate.getTextureAddress(0) & 0x3FFFFFFF) == (gstate.getFrameBufAddress() & 0x3FFFFFFF)) {
|
||||
|
||||
@@ -223,6 +223,7 @@ protected:
|
||||
numDrawVerts_ = 0;
|
||||
numDrawInds_ = 0;
|
||||
vertexCountInDrawCalls_ = 0;
|
||||
expandedVertsInDrawCalls_ = 0;
|
||||
numVertsToDecode_ = 0;
|
||||
decodeIndsCounter_ = 0;
|
||||
decodeVertsCounter_ = 0;
|
||||
@@ -331,6 +332,9 @@ protected:
|
||||
int numDrawVerts_ = 0;
|
||||
int numDrawInds_ = 0;
|
||||
int vertexCountInDrawCalls_ = 0;
|
||||
// How many vertices software transform expands the queued points, lines and rectangles to (4 per
|
||||
// point, line or rectangle). Must stay <= VERTEX_BUFFER_MAX, or the expansion drops the whole draw.
|
||||
int expandedVertsInDrawCalls_ = 0;
|
||||
// How many vertices DecodeVerts will produce for the queued draws. Must stay <= VERTEX_BUFFER_MAX.
|
||||
int numVertsToDecode_ = 0;
|
||||
|
||||
|
||||
@@ -233,6 +233,7 @@ void DrawEngineGLES::Flush() {
|
||||
numDrawVerts_ = 0;
|
||||
numDrawInds_ = 0;
|
||||
vertexCountInDrawCalls_ = 0;
|
||||
expandedVertsInDrawCalls_ = 0;
|
||||
numVertsToDecode_ = 0;
|
||||
decodeVertsCounter_ = 0;
|
||||
decodeIndsCounter_ = 0;
|
||||
|
||||
@@ -554,6 +554,7 @@ void DrawEngineVulkan::ResetAfterSkippedDraw() {
|
||||
numDrawVerts_ = 0;
|
||||
numDrawInds_ = 0;
|
||||
vertexCountInDrawCalls_ = 0;
|
||||
expandedVertsInDrawCalls_ = 0;
|
||||
numVertsToDecode_ = 0;
|
||||
decodeIndsCounter_ = 0;
|
||||
decodeVertsCounter_ = 0;
|
||||
|
||||
Reference in new issue
Block a user