mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-21 10:19:04 +02:00
Merge pull request #5808 from unknownbrackets/perf
More small performance tweaks based on ARM profiling
This commit is contained in:
commit
4931cd131f
4 files changed
+51
-29
No files matched your search
@@ -255,9 +255,13 @@ VertexDecoder *TransformDrawEngine::GetVertexDecoder(u32 vtype) {
|
||||
}
|
||||
|
||||
void TransformDrawEngine::SetupVertexDecoder(u32 vertType) {
|
||||
SetupVertexDecoderInternal(vertType);
|
||||
}
|
||||
|
||||
inline void TransformDrawEngine::SetupVertexDecoderInternal(u32 vertType) {
|
||||
// As the decoder depends on the UVGenMode when we use UV prescale, we simply mash it
|
||||
// into the top of the verttype where there are unused bits.
|
||||
u32 vertTypeID = (vertType & 0xFFFFFF) | (gstate.getUVGenMode() << 24);
|
||||
const u32 vertTypeID = (vertType & 0xFFFFFF) | (gstate.getUVGenMode() << 24);
|
||||
|
||||
// If vtype has changed, setup the vertex decoder.
|
||||
// TODO: Simply cache the setup decoders instead.
|
||||
@@ -280,7 +284,7 @@ void TransformDrawEngine::SubmitPrim(void *verts, void *inds, GEPrimitiveType pr
|
||||
}
|
||||
prevPrim_ = prim;
|
||||
|
||||
SetupVertexDecoder(vertType);
|
||||
SetupVertexDecoderInternal(vertType);
|
||||
|
||||
dec_->IncrementStat(STAT_VERTSSUBMITTED, vertexCount);
|
||||
|
||||
@@ -373,33 +377,45 @@ void TransformDrawEngine::DecodeVertsStep() {
|
||||
|
||||
// 1. Look ahead to find the max index, only looking as "matching" drawcalls.
|
||||
// Expand the lower and upper bounds as we go.
|
||||
int j = i + 1;
|
||||
int lastMatch = i;
|
||||
while (j < numDrawCalls) {
|
||||
if (drawCalls[j].verts != dc.verts)
|
||||
break;
|
||||
if (uvScale && memcmp(&uvScale[j], &uvScale[i], sizeof(uvScale[0])) != 0)
|
||||
break;
|
||||
const int total = numDrawCalls;
|
||||
if (uvScale) {
|
||||
for (int j = i + 1; j < total; ++j) {
|
||||
if (drawCalls[j].verts != dc.verts)
|
||||
break;
|
||||
if (memcmp(&uvScale[j], &uvScale[i], sizeof(uvScale[0])) != 0)
|
||||
break;
|
||||
|
||||
indexLowerBound = std::min(indexLowerBound, (int)drawCalls[j].indexLowerBound);
|
||||
indexUpperBound = std::max(indexUpperBound, (int)drawCalls[j].indexUpperBound);
|
||||
lastMatch = j;
|
||||
j++;
|
||||
}
|
||||
indexLowerBound = std::min(indexLowerBound, (int)drawCalls[j].indexLowerBound);
|
||||
indexUpperBound = std::max(indexUpperBound, (int)drawCalls[j].indexUpperBound);
|
||||
lastMatch = j;
|
||||
}
|
||||
} else {
|
||||
for (int j = i + 1; j < total; ++j) {
|
||||
if (drawCalls[j].verts != dc.verts)
|
||||
break;
|
||||
|
||||
// 2. Loop through the drawcalls, translating indices as we go.
|
||||
for (j = i; j <= lastMatch; j++) {
|
||||
switch (indexType) {
|
||||
case GE_VTYPE_IDX_8BIT >> GE_VTYPE_IDX_SHIFT:
|
||||
indexGen.TranslatePrim(drawCalls[j].prim, drawCalls[j].vertexCount, (const u8 *)drawCalls[j].inds, indexLowerBound);
|
||||
break;
|
||||
case GE_VTYPE_IDX_16BIT >> GE_VTYPE_IDX_SHIFT:
|
||||
indexGen.TranslatePrim(drawCalls[j].prim, drawCalls[j].vertexCount, (const u16 *)drawCalls[j].inds, indexLowerBound);
|
||||
break;
|
||||
indexLowerBound = std::min(indexLowerBound, (int)drawCalls[j].indexLowerBound);
|
||||
indexUpperBound = std::max(indexUpperBound, (int)drawCalls[j].indexUpperBound);
|
||||
lastMatch = j;
|
||||
}
|
||||
}
|
||||
|
||||
int vertexCount = indexUpperBound - indexLowerBound + 1;
|
||||
// 2. Loop through the drawcalls, translating indices as we go.
|
||||
switch (indexType) {
|
||||
case GE_VTYPE_IDX_8BIT >> GE_VTYPE_IDX_SHIFT:
|
||||
for (int j = i; j <= lastMatch; j++) {
|
||||
indexGen.TranslatePrim(drawCalls[j].prim, drawCalls[j].vertexCount, (const u8 *)drawCalls[j].inds, indexLowerBound);
|
||||
}
|
||||
break;
|
||||
case GE_VTYPE_IDX_16BIT >> GE_VTYPE_IDX_SHIFT:
|
||||
for (int j = i; j <= lastMatch; j++) {
|
||||
indexGen.TranslatePrim(drawCalls[j].prim, drawCalls[j].vertexCount, (const u16 *)drawCalls[j].inds, indexLowerBound);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
const int vertexCount = indexUpperBound - indexLowerBound + 1;
|
||||
// 3. Decode that range of vertex data.
|
||||
dec_->DecodeVerts(decoded + decodedVerts_ * (int)dec_->GetDecVtxFmt().stride,
|
||||
dc.verts, indexLowerBound, indexUpperBound);
|
||||
|
||||
@@ -124,6 +124,7 @@ public:
|
||||
void ClearTrackedVertexArrays();
|
||||
|
||||
void SetupVertexDecoder(u32 vertType);
|
||||
inline void SetupVertexDecoderInternal(u32 vertType);
|
||||
|
||||
// This requires a SetupVertexDecoder call first.
|
||||
int EstimatePerVertexCost() {
|
||||
|
||||
+7
-5
@@ -559,17 +559,19 @@ void GPUCommon::SlowRunLoop(DisplayList &list)
|
||||
// The newPC parameter is used for jumps, we don't count cycles between.
|
||||
void GPUCommon::UpdatePC(u32 currentPC, u32 newPC) {
|
||||
// Rough estimate, 2 CPU ticks (it's double the clock rate) per GPU instruction.
|
||||
int executed = (currentPC - cycleLastPC) / 4;
|
||||
u32 executed = (currentPC - cycleLastPC) / 4;
|
||||
cyclesExecuted += 2 * executed;
|
||||
gpuStats.otherGPUCycles += 2 * executed;
|
||||
cycleLastPC = newPC == 0 ? currentPC : newPC;
|
||||
cycleLastPC = currentPC;
|
||||
|
||||
gpuStats.gpuCommandsAtCallLevel[std::min(currentList->stackptr, 3)] += executed;
|
||||
if (g_Config.bShowDebugStats) {
|
||||
gpuStats.otherGPUCycles += 2 * executed;
|
||||
gpuStats.gpuCommandsAtCallLevel[std::min(currentList->stackptr, 3)] += executed;
|
||||
}
|
||||
|
||||
// Exit the runloop and recalculate things. This happens a lot in some games.
|
||||
easy_guard innerGuard(listLock);
|
||||
if (currentList)
|
||||
downcount = currentList->stall == 0 ? 0x0FFFFFFF : (currentList->stall - cycleLastPC) / 4;
|
||||
downcount = currentList->stall == 0 ? 0x0FFFFFFF : (currentList->stall - currentPC) / 4;
|
||||
else
|
||||
downcount = 0;
|
||||
}
|
||||
|
||||
+4
-1
@@ -81,7 +81,10 @@ protected:
|
||||
// To avoid virtual calls to PreExecuteOp().
|
||||
virtual void FastRunLoop(DisplayList &list) = 0;
|
||||
void SlowRunLoop(DisplayList &list);
|
||||
void UpdatePC(u32 currentPC, u32 newPC = 0);
|
||||
void UpdatePC(u32 currentPC, u32 newPC);
|
||||
void UpdatePC(u32 currentPC) {
|
||||
UpdatePC(currentPC, currentPC);
|
||||
}
|
||||
void UpdateState(GPUState state);
|
||||
void PopDLQueue();
|
||||
void CheckDrawSync();
|
||||
|
||||
Reference in new issue
Block a user