mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-12 17:48:43 +00:00
Merge pull request #4343 from unknownbrackets/gpu-minor
Don't crash if there are too many vertices in a row + softgpu frameskip
This commit is contained in:
commit
e0bc0a3bf1
@ -69,9 +69,10 @@ int D3DPrimCount(D3DPRIMITIVETYPE prim, int size) {
|
||||
}
|
||||
|
||||
enum {
|
||||
DECODED_VERTEX_BUFFER_SIZE = 65536 * 48,
|
||||
DECODED_INDEX_BUFFER_SIZE = 65536 * 20,
|
||||
TRANSFORMED_VERTEX_BUFFER_SIZE = 65536 * sizeof(TransformedVertex)
|
||||
VERTEX_BUFFER_MAX = 65536,
|
||||
DECODED_VERTEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * 48,
|
||||
DECODED_INDEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * 20,
|
||||
TRANSFORMED_VERTEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * sizeof(TransformedVertex)
|
||||
};
|
||||
|
||||
|
||||
@ -90,6 +91,7 @@ TransformDrawEngineDX9::TransformDrawEngineDX9()
|
||||
textureCache_(0),
|
||||
framebufferManager_(0),
|
||||
numDrawCalls(0),
|
||||
vertexCountInDrawCalls(0),
|
||||
uvScale(0) {
|
||||
decimationCounter_ = VERTEXCACHE_DECIMATION_INTERVAL;
|
||||
// Allocate nicely aligned memory. Maybe graphics drivers will
|
||||
@ -914,7 +916,7 @@ void TransformDrawEngineDX9::SubmitPrim(void *verts, void *inds, GEPrimitiveType
|
||||
if (vertexCount == 0)
|
||||
return; // we ignore zero-sized draw calls.
|
||||
|
||||
if (!indexGen.PrimCompatible(prevPrim_, prim) || numDrawCalls >= MAX_DEFERRED_DRAW_CALLS)
|
||||
if (!indexGen.PrimCompatible(prevPrim_, prim) || numDrawCalls >= MAX_DEFERRED_DRAW_CALLS || vertexCountInDrawCalls + vertexCount > VERTEX_BUFFER_MAX)
|
||||
Flush();
|
||||
|
||||
// TODO: Is this the right thing to do?
|
||||
@ -951,6 +953,7 @@ void TransformDrawEngineDX9::SubmitPrim(void *verts, void *inds, GEPrimitiveType
|
||||
uvScale[numDrawCalls] = gstate_c.uv;
|
||||
}
|
||||
numDrawCalls++;
|
||||
vertexCountInDrawCalls += vertexCount;
|
||||
}
|
||||
|
||||
void TransformDrawEngineDX9::DecodeVerts() {
|
||||
@ -1330,6 +1333,7 @@ rotateVBO:
|
||||
indexGen.Reset();
|
||||
collectedVerts = 0;
|
||||
numDrawCalls = 0;
|
||||
vertexCountInDrawCalls = 0;
|
||||
prevPrim_ = GE_PRIM_INVALID;
|
||||
|
||||
#ifndef _XBOX
|
||||
|
@ -186,6 +186,7 @@ private:
|
||||
enum { MAX_DEFERRED_DRAW_CALLS = 128 };
|
||||
DeferredDrawCall drawCalls[MAX_DEFERRED_DRAW_CALLS];
|
||||
int numDrawCalls;
|
||||
int vertexCountInDrawCalls;
|
||||
|
||||
int decimationCounter_;
|
||||
|
||||
|
@ -99,9 +99,10 @@ const GLuint glprim[8] = {
|
||||
};
|
||||
|
||||
enum {
|
||||
DECODED_VERTEX_BUFFER_SIZE = 65536 * 48,
|
||||
DECODED_INDEX_BUFFER_SIZE = 65536 * 20,
|
||||
TRANSFORMED_VERTEX_BUFFER_SIZE = 65536 * sizeof(TransformedVertex)
|
||||
VERTEX_BUFFER_MAX = 65536,
|
||||
DECODED_VERTEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * 48,
|
||||
DECODED_INDEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * 20,
|
||||
TRANSFORMED_VERTEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * sizeof(TransformedVertex)
|
||||
};
|
||||
|
||||
#define QUAD_INDICES_MAX 32768
|
||||
@ -123,6 +124,7 @@ TransformDrawEngine::TransformDrawEngine()
|
||||
textureCache_(0),
|
||||
framebufferManager_(0),
|
||||
numDrawCalls(0),
|
||||
vertexCountInDrawCalls(0),
|
||||
uvScale(0) {
|
||||
decimationCounter_ = VERTEXCACHE_DECIMATION_INTERVAL;
|
||||
// Allocate nicely aligned memory. Maybe graphics drivers will
|
||||
@ -914,7 +916,7 @@ void TransformDrawEngine::SubmitPrim(void *verts, void *inds, GEPrimitiveType pr
|
||||
if (vertexCount == 0)
|
||||
return; // we ignore zero-sized draw calls.
|
||||
|
||||
if (!indexGen.PrimCompatible(prevPrim_, prim) || numDrawCalls >= MAX_DEFERRED_DRAW_CALLS)
|
||||
if (!indexGen.PrimCompatible(prevPrim_, prim) || numDrawCalls >= MAX_DEFERRED_DRAW_CALLS || vertexCountInDrawCalls + vertexCount > VERTEX_BUFFER_MAX)
|
||||
Flush();
|
||||
|
||||
// TODO: Is this the right thing to do?
|
||||
@ -951,6 +953,7 @@ void TransformDrawEngine::SubmitPrim(void *verts, void *inds, GEPrimitiveType pr
|
||||
uvScale[numDrawCalls] = gstate_c.uv;
|
||||
}
|
||||
numDrawCalls++;
|
||||
vertexCountInDrawCalls += vertexCount;
|
||||
}
|
||||
|
||||
void TransformDrawEngine::DecodeVerts() {
|
||||
@ -1326,6 +1329,7 @@ rotateVBO:
|
||||
indexGen.Reset();
|
||||
collectedVerts = 0;
|
||||
numDrawCalls = 0;
|
||||
vertexCountInDrawCalls = 0;
|
||||
prevPrim_ = GE_PRIM_INVALID;
|
||||
|
||||
#ifndef USING_GLES2
|
||||
|
@ -191,6 +191,7 @@ private:
|
||||
enum { MAX_DEFERRED_DRAW_CALLS = 128 };
|
||||
DeferredDrawCall drawCalls[MAX_DEFERRED_DRAW_CALLS];
|
||||
int numDrawCalls;
|
||||
int vertexCountInDrawCalls;
|
||||
|
||||
int decimationCounter_;
|
||||
|
||||
|
@ -268,6 +268,32 @@ void SoftGPU::FastRunLoop(DisplayList &list) {
|
||||
}
|
||||
}
|
||||
|
||||
int EstimatePerVertexCost() {
|
||||
// TODO: This is transform cost, also account for rasterization cost somehow... although it probably
|
||||
// runs in parallel with transform.
|
||||
|
||||
// Also, this is all pure guesswork. If we can find a way to do measurements, that would be great.
|
||||
|
||||
// GTA wants a low value to run smooth, GoW wants a high value (otherwise it thinks things
|
||||
// went too fast and starts doing all the work over again).
|
||||
|
||||
int cost = 20;
|
||||
if (gstate.isLightingEnabled()) {
|
||||
cost += 10;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (gstate.isLightChanEnabled(i))
|
||||
cost += 10;
|
||||
}
|
||||
if (gstate.getUVGenMode() != GE_TEXMAP_TEXTURE_COORDS) {
|
||||
cost += 20;
|
||||
}
|
||||
// TODO: morphcount
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
void SoftGPU::ExecuteOp(u32 op, u32 diff)
|
||||
{
|
||||
u32 cmd = op >> 24;
|
||||
@ -303,6 +329,7 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
|
||||
|
||||
if (type != GE_PRIM_TRIANGLES && type != GE_PRIM_TRIANGLE_STRIP && type != GE_PRIM_TRIANGLE_FAN && type != GE_PRIM_RECTANGLES) {
|
||||
ERROR_LOG_REPORT(G3D, "Software: DL DrawPrim type: %s count: %i vaddr= %08x, iaddr= %08x", type<7 ? types[type] : "INVALID", count, gstate_c.vertexAddr, gstate_c.indexAddr);
|
||||
cyclesExecuted += EstimatePerVertexCost() * count;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -321,7 +348,10 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
|
||||
indices = Memory::GetPointer(gstate_c.indexAddr);
|
||||
}
|
||||
|
||||
TransformUnit::SubmitPrimitive(verts, indices, type, count, gstate.vertType);
|
||||
cyclesExecuted += EstimatePerVertexCost() * count;
|
||||
if (!(gstate_c.skipDrawReason & SKIPDRAW_SKIPFRAME)) {
|
||||
TransformUnit::SubmitPrimitive(verts, indices, type, count, gstate.vertType);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -361,7 +391,9 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
|
||||
break;
|
||||
}
|
||||
|
||||
TransformUnit::SubmitSpline(control_points, indices, sp_ucount, sp_vcount, sp_utype, sp_vtype, gstate.getPatchPrimitiveType(), gstate.vertType);
|
||||
if (!(gstate_c.skipDrawReason & SKIPDRAW_SKIPFRAME)) {
|
||||
TransformUnit::SubmitSpline(control_points, indices, sp_ucount, sp_vcount, sp_utype, sp_vtype, gstate.getPatchPrimitiveType(), gstate.vertType);
|
||||
}
|
||||
DEBUG_LOG(G3D,"DL DRAW SPLINE: %i x %i, %i x %i", sp_ucount, sp_vcount, sp_utype, sp_vtype);
|
||||
}
|
||||
break;
|
||||
|
@ -73,6 +73,10 @@ public:
|
||||
fullInfo = "Software";
|
||||
}
|
||||
|
||||
virtual bool FramebufferReallyDirty() {
|
||||
return !(gstate_c.skipDrawReason & SKIPDRAW_SKIPFRAME);
|
||||
}
|
||||
|
||||
virtual bool GetCurrentFramebuffer(GPUDebugBuffer &buffer);
|
||||
virtual bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer);
|
||||
virtual bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer);
|
||||
|
Loading…
x
Reference in New Issue
Block a user