mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
GPU: Correct bounding box for larger counts.
Matches tests on a PSP with float/transform format.
This commit is contained in:
parent
299033929a
commit
6ddf22487b
@ -244,7 +244,7 @@ void DrawEngineCommon::DispatchSubmitImm(GEPrimitiveType prim, TransformedVertex
|
||||
//
|
||||
// It does the simplest and safest test possible: If all points of a bbox is outside a single of
|
||||
// our clipping planes, we reject the box. Tighter bounds would be desirable but would take more calculations.
|
||||
bool DrawEngineCommon::TestBoundingBox(const void* control_points, int vertexCount, u32 vertType, int *bytesRead) {
|
||||
bool DrawEngineCommon::TestBoundingBox(const void* control_points, int vertexCount, u32 vertType) {
|
||||
SimpleVertex *corners = (SimpleVertex *)(decoded + 65536 * 12);
|
||||
float *verts = (float *)(decoded + 65536 * 18);
|
||||
|
||||
@ -252,19 +252,16 @@ bool DrawEngineCommon::TestBoundingBox(const void* control_points, int vertexCou
|
||||
// and a large vertex format.
|
||||
if ((vertType & 0xFFFFFF) == GE_VTYPE_POS_FLOAT) {
|
||||
verts = (float *)control_points;
|
||||
*bytesRead = 3 * sizeof(float) * vertexCount;
|
||||
} else if ((vertType & 0xFFFFFF) == GE_VTYPE_POS_8BIT) {
|
||||
const s8 *vtx = (const s8 *)control_points;
|
||||
for (int i = 0; i < vertexCount * 3; i++) {
|
||||
verts[i] = vtx[i] * (1.0f / 128.0f);
|
||||
}
|
||||
*bytesRead = 3 * sizeof(s8) * vertexCount;
|
||||
} else if ((vertType & 0xFFFFFF) == GE_VTYPE_POS_16BIT) {
|
||||
const s16 *vtx = (const s16*)control_points;
|
||||
for (int i = 0; i < vertexCount * 3; i++) {
|
||||
verts[i] = vtx[i] * (1.0f / 32768.0f);
|
||||
}
|
||||
*bytesRead = 3 * sizeof(s16) * vertexCount;
|
||||
} else {
|
||||
// Simplify away bones and morph before proceeding
|
||||
u8 *temp_buffer = decoded + 65536 * 24;
|
||||
@ -275,7 +272,6 @@ bool DrawEngineCommon::TestBoundingBox(const void* control_points, int vertexCou
|
||||
verts[i * 3 + 1] = corners[i].pos.y;
|
||||
verts[i * 3 + 2] = corners[i].pos.z;
|
||||
}
|
||||
*bytesRead = vertexSize * vertexCount;
|
||||
}
|
||||
|
||||
Plane planes[6];
|
||||
|
@ -92,7 +92,7 @@ public:
|
||||
|
||||
virtual void DispatchSubmitImm(GEPrimitiveType prim, TransformedVertex *buffer, int vertexCount, int cullMode, bool continuation);
|
||||
|
||||
bool TestBoundingBox(const void* control_points, int vertexCount, u32 vertType, int *bytesRead);
|
||||
bool TestBoundingBox(const void* control_points, int vertexCount, u32 vertType);
|
||||
|
||||
void SubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead);
|
||||
template<class Surface>
|
||||
|
@ -2153,13 +2153,17 @@ void GPUCommon::Execute_Spline(u32 op, u32 diff) {
|
||||
|
||||
void GPUCommon::Execute_BoundingBox(u32 op, u32 diff) {
|
||||
// Just resetting, nothing to check bounds for.
|
||||
const u32 count = op & 0xFFFFFF;
|
||||
const u32 count = op & 0xFFFF;
|
||||
if (count == 0) {
|
||||
currentList->bboxResult = false;
|
||||
return;
|
||||
}
|
||||
if (((count & 7) == 0) && count <= 64) { // Sanity check
|
||||
const void *control_points = Memory::GetPointer(gstate_c.vertexAddr);
|
||||
|
||||
VertexDecoder *dec = drawEngineCommon_->GetVertexDecoder(gstate.vertType);
|
||||
int bytesRead = dec->VertexSize() * count;
|
||||
|
||||
if (Memory::IsValidRange(gstate_c.vertexAddr, bytesRead)) {
|
||||
const void *control_points = Memory::GetPointerUnchecked(gstate_c.vertexAddr);
|
||||
if (!control_points) {
|
||||
ERROR_LOG_REPORT_ONCE(boundingbox, G3D, "Invalid verts in bounding box check");
|
||||
currentList->bboxResult = true;
|
||||
@ -2174,8 +2178,17 @@ void GPUCommon::Execute_BoundingBox(u32 op, u32 diff) {
|
||||
}
|
||||
|
||||
// Test if the bounding box is within the drawing region.
|
||||
int bytesRead;
|
||||
currentList->bboxResult = drawEngineCommon_->TestBoundingBox(control_points, count, gstate.vertType, &bytesRead);
|
||||
// The PSP only seems to vary the result based on a single range of 0x100.
|
||||
if (count > 0x200) {
|
||||
// The second to last set of 0x100 is checked (even for odd counts.)
|
||||
size_t skipSize = (count - 0x200) * dec->VertexSize();
|
||||
currentList->bboxResult = drawEngineCommon_->TestBoundingBox((const uint8_t *)control_points + skipSize, 0x100, gstate.vertType);
|
||||
} else if (count > 0x100) {
|
||||
int checkSize = count - 0x100;
|
||||
currentList->bboxResult = drawEngineCommon_->TestBoundingBox(control_points, checkSize, gstate.vertType);
|
||||
} else {
|
||||
currentList->bboxResult = drawEngineCommon_->TestBoundingBox(control_points, count, gstate.vertType);
|
||||
}
|
||||
AdvanceVerts(gstate.vertType, count, bytesRead);
|
||||
} else {
|
||||
ERROR_LOG_REPORT_ONCE(boundingbox, G3D, "Bad bounding box data: %06x", count);
|
||||
|
Loading…
Reference in New Issue
Block a user