mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-10 21:16:24 +02:00
DrawEngine; Convert strip sequences in a tight loop
This commit is contained in:
1 parent
15df71c02a
commit
cd35252400
4 files changed
+59
-38
No files matched your search
@@ -610,7 +610,7 @@ u32 DrawEngineCommon::ComputeMiniHash() {
|
||||
}
|
||||
for (int i = 0; i < numDrawInds_; i += step) {
|
||||
const DeferredInds &di = drawInds_[i];
|
||||
if (di.inds) {
|
||||
if (di.indexType != 0) {
|
||||
fullhash += ComputeMiniHashRange(di.inds, indexSize * di.vertexCount);
|
||||
}
|
||||
}
|
||||
@@ -638,8 +638,10 @@ uint32_t DrawEngineCommon::ComputeDrawcallsHash() const {
|
||||
}
|
||||
for (int j = 0; j < numDrawInds_; j++) {
|
||||
u32 dhash = dcid;
|
||||
dhash = __rotl(dhash ^ (u32)(uintptr_t)drawInds_[j].inds, 19);
|
||||
dcid = lowbias32_r(__rotl(dhash ^ (u32)drawInds_[j].indexType, 7));
|
||||
if (drawInds_[j].inds) {
|
||||
dhash = __rotl(dhash ^ (u32)(uintptr_t)drawInds_[j].inds, 19);
|
||||
dcid = lowbias32_r(__rotl(dhash ^ (u32)drawInds_[j].indexType, 7));
|
||||
}
|
||||
}
|
||||
return dcid;
|
||||
}
|
||||
@@ -678,31 +680,46 @@ uint64_t DrawEngineCommon::ComputeHash() {
|
||||
return fullhash;
|
||||
}
|
||||
|
||||
bool DrawEngineCommon::ExtendNonIndexedPrim(GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) {
|
||||
if (numDrawInds_ >= MAX_DEFERRED_DRAW_INDS || vertexCountInDrawCalls_ + vertexCount > VERTEX_BUFFER_MAX) {
|
||||
return false;
|
||||
}
|
||||
int DrawEngineCommon::ExtendNonIndexedPrim(const uint32_t *cmd, u32 vertTypeID, int cullMode, int *bytesRead, bool isTriangle) {
|
||||
const uint32_t *start = cmd;
|
||||
int prevDrawVerts = numDrawVerts_ - 1;
|
||||
DeferredVerts &dv = drawVerts_[prevDrawVerts];
|
||||
int offset = dv.vertexCount;
|
||||
|
||||
_dbg_assert_(numDrawInds_ < MAX_DEFERRED_DRAW_INDS);
|
||||
_dbg_assert_(numDrawVerts_ > 0);
|
||||
*bytesRead = vertexCount * dec_->VertexSize();
|
||||
|
||||
DeferredInds &di = drawInds_[numDrawInds_++];
|
||||
di.inds = nullptr;
|
||||
di.indexType = 0;
|
||||
di.prim = prim;
|
||||
di.cullMode = cullMode;
|
||||
di.vertexCount = vertexCount;
|
||||
di.vertDecodeIndex = numDrawVerts_ - 1;
|
||||
while (true) {
|
||||
uint32_t data = *cmd;
|
||||
if ((data & 0xFFF80000) != 0x04000000) {
|
||||
break;
|
||||
}
|
||||
GEPrimitiveType newPrim = static_cast<GEPrimitiveType>((data >> 16) & 7);
|
||||
if (IsTrianglePrim(newPrim) != isTriangle)
|
||||
break;
|
||||
int vertexCount = data & 0xFFFF;
|
||||
if (numDrawInds_ >= MAX_DEFERRED_DRAW_INDS || vertexCountInDrawCalls_ + vertexCount > VERTEX_BUFFER_MAX) {
|
||||
break;
|
||||
}
|
||||
DeferredInds &di = drawInds_[numDrawInds_++];
|
||||
di.indexType = 0;
|
||||
di.prim = newPrim;
|
||||
di.cullMode = cullMode;
|
||||
di.vertexCount = vertexCount;
|
||||
di.vertDecodeIndex = prevDrawVerts;
|
||||
di.offset = offset;
|
||||
offset += vertexCount;
|
||||
cmd++;
|
||||
}
|
||||
|
||||
DeferredVerts &dv = drawVerts_[numDrawVerts_ - 1];
|
||||
int offset = dv.vertexCount;
|
||||
di.offset = offset;
|
||||
dv.vertexCount += vertexCount;
|
||||
_dbg_assert_(cmd != start);
|
||||
|
||||
int totalCount = offset - dv.vertexCount;
|
||||
dv.vertexCount = offset;
|
||||
dv.indexUpperBound = dv.vertexCount - 1;
|
||||
vertexCountInDrawCalls_ += vertexCount;
|
||||
|
||||
return true;
|
||||
vertexCountInDrawCalls_ += totalCount;
|
||||
*bytesRead = totalCount * dec_->VertexSize();
|
||||
return cmd - start;
|
||||
}
|
||||
|
||||
// vertTypeID is the vertex type but with the UVGen mode smashed into the top bits.
|
||||
|
||||
@@ -111,7 +111,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool ExtendNonIndexedPrim(GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead);
|
||||
int ExtendNonIndexedPrim(const uint32_t *cmd, u32 vertTypeID, int cullMode, int *bytesRead, bool isTriangle);
|
||||
void SubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead);
|
||||
template<class Surface>
|
||||
void SubmitCurve(const void *control_points, const void *indices, Surface &surface, u32 vertType, int *bytesRead, const char *scope);
|
||||
|
||||
+12
-11
@@ -67,6 +67,18 @@ struct TransformedVertex {
|
||||
}
|
||||
};
|
||||
|
||||
inline bool IsTrianglePrim(GEPrimitiveType prim) {
|
||||
// TODO: KEEP_PREVIOUS is mistakenly treated as TRIANGLE here... This isn't new.
|
||||
//
|
||||
// Interesting optimization, but not confident in performance:
|
||||
// static const bool p[8] = { false, false, false, true, true, true, false, true };
|
||||
// 10111000 = 0xB8;
|
||||
// return (0xB8U >> (u8)prim) & 1;
|
||||
|
||||
return prim > GE_PRIM_LINE_STRIP && prim != GE_PRIM_RECTANGLES;
|
||||
}
|
||||
|
||||
|
||||
class GPUCommon : public GPUInterface, public GPUDebugInterface {
|
||||
public:
|
||||
GPUCommon(GraphicsContext *gfxCtx, Draw::DrawContext *draw);
|
||||
@@ -219,17 +231,6 @@ protected:
|
||||
|
||||
virtual void CheckRenderResized() {}
|
||||
|
||||
inline bool IsTrianglePrim(GEPrimitiveType prim) const {
|
||||
// TODO: KEEP_PREVIOUS is mistakenly treated as TRIANGLE here... This isn't new.
|
||||
//
|
||||
// Interesting optimization, but not confident in performance:
|
||||
// static const bool p[8] = { false, false, false, true, true, true, false, true };
|
||||
// 10111000 = 0xB8;
|
||||
// return (0xB8U >> (u8)prim) & 1;
|
||||
|
||||
return prim > GE_PRIM_LINE_STRIP && prim != GE_PRIM_RECTANGLES;
|
||||
}
|
||||
|
||||
void SetDrawType(DrawType type, GEPrimitiveType prim) {
|
||||
if (type != lastDraw_) {
|
||||
// We always flush when drawing splines/beziers so no need to do so here
|
||||
|
||||
+7
-4
@@ -1026,11 +1026,14 @@ void GPUCommonHW::Execute_Prim(u32 op, u32 diff) {
|
||||
// Non-indexed draws can be cheaply merged if vertexAddr hasn't changed, that means the vertices
|
||||
// are consecutive in memory.
|
||||
_dbg_assert_((vertexType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_NONE);
|
||||
if (drawEngineCommon_->ExtendNonIndexedPrim(newPrim, count, vertTypeID, cullMode, &bytesRead)) {
|
||||
gstate_c.vertexAddr += bytesRead;
|
||||
totalVertCount += count;
|
||||
break;
|
||||
int commandsExecuted = drawEngineCommon_->ExtendNonIndexedPrim(src, vertTypeID, cullMode, &bytesRead, isTriangle);
|
||||
if (!commandsExecuted) {
|
||||
goto bail;
|
||||
}
|
||||
src += commandsExecuted - 1;
|
||||
gstate_c.vertexAddr += bytesRead;
|
||||
totalVertCount += count;
|
||||
break;
|
||||
}
|
||||
|
||||
// Failed, or can't extend? Do a normal submit.
|
||||
|
||||
Reference in new issue
Block a user