mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Don't forget to update the vertex addr even when culling 2D draws
Fixes #20454
This commit is contained in:
@@ -527,25 +527,21 @@ bool DrawEngineCommon::TestBoundingBoxFast(const void *vdata, int vertexCount, c
|
||||
|
||||
// 2D bounding box test against scissor. No indexing yet.
|
||||
// Only supports non-indexed draws with float positions.
|
||||
bool DrawEngineCommon::TestBoundingBoxThrough(const void *vdata, int vertexCount, const VertexDecoder *dec, u32 vertType) {
|
||||
bool DrawEngineCommon::TestBoundingBoxThrough(const void *vdata, int vertexCount, const VertexDecoder *dec, u32 vertType, int *bytesRead) {
|
||||
// Grab temp buffer space from large offsets in decoded_. Not exactly safe for large draws.
|
||||
if (vertexCount > 16) {
|
||||
return true;
|
||||
}
|
||||
|
||||
float *verts = (float *)(decoded_ + 65536 * 18);
|
||||
|
||||
// Although this may lead to drawing that shouldn't happen, the viewport is more complex on VR.
|
||||
// Let's always say objects are within bounds.
|
||||
if (gstate_c.Use(GPU_USE_VIRTUAL_REALITY))
|
||||
return true;
|
||||
|
||||
// Try to skip NormalizeVertices if it's pure positions. No need to bother with a vertex decoder
|
||||
// and a large vertex format.
|
||||
u8 *temp_buffer = decoded_ + 65536 * 24;
|
||||
// Simple, most common case.
|
||||
int stride = dec->VertexSize();
|
||||
int offset = dec->posoff;
|
||||
const int stride = dec->VertexSize();
|
||||
const int posOffset = dec->posoff;
|
||||
|
||||
*bytesRead = stride * vertexCount;
|
||||
|
||||
bool allOutsideLeft = true;
|
||||
bool allOutsideTop = true;
|
||||
@@ -559,10 +555,11 @@ bool DrawEngineCommon::TestBoundingBoxThrough(const void *vdata, int vertexCount
|
||||
switch (vertType & GE_VTYPE_POS_MASK) {
|
||||
case GE_VTYPE_POS_FLOAT:
|
||||
{
|
||||
// TODO: This can be SIMD'd, with some trickery.
|
||||
for (int i = 0; i < vertexCount; i++) {
|
||||
float *pos = (float*)((const u8 *)vdata + stride * i + offset);
|
||||
float x = pos[0];
|
||||
float y = pos[1];
|
||||
const float *pos = (const float*)((const u8 *)vdata + stride * i + posOffset);
|
||||
const float x = pos[0];
|
||||
const float y = pos[1];
|
||||
if (x >= left) {
|
||||
allOutsideLeft = false;
|
||||
}
|
||||
@@ -582,8 +579,9 @@ bool DrawEngineCommon::TestBoundingBoxThrough(const void *vdata, int vertexCount
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
// Shouldn't end up here with the checks outside this function.
|
||||
_dbg_assert_(false);
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ public:
|
||||
// This is a less accurate version of TestBoundingBox, but faster. Can have more false positives.
|
||||
// Doesn't support indexing.
|
||||
bool TestBoundingBoxFast(const void *control_points, int vertexCount, const VertexDecoder *dec, u32 vertType);
|
||||
bool TestBoundingBoxThrough(const void *vdata, int vertexCount, const VertexDecoder *dec, u32 vertType);
|
||||
bool TestBoundingBoxThrough(const void *vdata, int vertexCount, const VertexDecoder *dec, u32 vertType, int *bytesRead);
|
||||
|
||||
void FlushPartialDecode() {
|
||||
DecodeVerts(dec_, decoded_);
|
||||
|
||||
+7
-3
@@ -1000,7 +1000,6 @@ void GPUCommonHW::Execute_Prim(u32 op, u32 diff) {
|
||||
canExtend = false;
|
||||
}
|
||||
|
||||
int bytesRead = 0;
|
||||
gstate_c.UpdateUVScaleOffset();
|
||||
|
||||
// cull mode
|
||||
@@ -1011,11 +1010,14 @@ void GPUCommonHW::Execute_Prim(u32 op, u32 diff) {
|
||||
|
||||
// Through mode early-out for simple float 2D draws, like in Fate Extra CCC (very beneficial there due to avoiding texture loads)
|
||||
if ((vertexType & (GE_VTYPE_THROUGH_MASK | GE_VTYPE_POS_MASK | GE_VTYPE_IDX_MASK)) == (GE_VTYPE_THROUGH_MASK | GE_VTYPE_POS_FLOAT | GE_VTYPE_IDX_NONE)) {
|
||||
if (!drawEngineCommon_->TestBoundingBoxThrough(verts, count, decoder, vertexType)) {
|
||||
int bytesRead = 0;
|
||||
if (!drawEngineCommon_->TestBoundingBoxThrough(verts, count, decoder, vertexType, &bytesRead)) {
|
||||
gpuStats.numCulledDraws++;
|
||||
int cycles = vertexCost_ * count;
|
||||
gpuStats.vertexGPUCycles += cycles;
|
||||
cyclesExecuted += cycles;
|
||||
// NOTE! We still have to advance vertex pointers!
|
||||
gstate_c.vertexAddr += bytesRead; // We know from the above check that it's not an indexed draw.
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1044,6 +1046,8 @@ void GPUCommonHW::Execute_Prim(u32 op, u32 diff) {
|
||||
}
|
||||
}
|
||||
|
||||
int bytesRead = 0;
|
||||
|
||||
// If the first one in a batch passes, let's assume the whole batch passes.
|
||||
// Cuts down on checking, while not losing that much efficiency.
|
||||
bool onePassed = false;
|
||||
@@ -1357,7 +1361,7 @@ void GPUCommonHW::Execute_Bezier(u32 op, u32 diff) {
|
||||
gstate_c.submitType = SubmitType::DRAW;
|
||||
|
||||
// After drawing, we advance pointers - see SubmitPrim which does the same.
|
||||
int count = surface.num_points_u * surface.num_points_v;
|
||||
const int count = surface.num_points_u * surface.num_points_v;
|
||||
AdvanceVerts(gstate.vertType, count, bytesRead);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user