mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-27 07:20:49 +00:00
GPU: Avoid spline crashes on bad data.
If we get 0 prims, we can generate confusing index bounds and go out of bounds. Similarly, if we get a crazy number of control points and fail to allocate, we can crash.
This commit is contained in:
parent
12405709f0
commit
e82fd3bd33
@ -321,7 +321,8 @@ ControlPoints::ControlPoints(const SimpleVertex *const *points, int size, Simple
|
||||
pos = (Vec3f *)managedBuf.Allocate(sizeof(Vec3f) * size);
|
||||
tex = (Vec2f *)managedBuf.Allocate(sizeof(Vec2f) * size);
|
||||
col = (Vec4f *)managedBuf.Allocate(sizeof(Vec4f) * size);
|
||||
Convert(points, size);
|
||||
if (pos && tex && col)
|
||||
Convert(points, size);
|
||||
}
|
||||
|
||||
void ControlPoints::Convert(const SimpleVertex *const *points, int size) {
|
||||
@ -554,7 +555,10 @@ void DrawEngineCommon::SubmitCurve(const void *control_points, const void *indic
|
||||
HardwareTessellation(output, surface, origVertType, points, tessDataTransfer);
|
||||
} else {
|
||||
ControlPoints cpoints(points, num_points, managedBuf);
|
||||
SoftwareTessellation(output, surface, origVertType, cpoints);
|
||||
if (cpoints.IsValid())
|
||||
SoftwareTessellation(output, surface, origVertType, cpoints);
|
||||
else
|
||||
ERROR_LOG(G3D, "Failed to allocate space for control point values, skipping curve draw");
|
||||
}
|
||||
|
||||
u32 vertTypeWithIndex16 = (vertType & ~GE_VTYPE_IDX_MASK) | GE_VTYPE_IDX_16BIT;
|
||||
@ -571,7 +575,8 @@ void DrawEngineCommon::SubmitCurve(const void *control_points, const void *indic
|
||||
|
||||
uint32_t vertTypeID = GetVertTypeID(vertTypeWithIndex16, gstate.getUVGenMode());
|
||||
int generatedBytesRead;
|
||||
DispatchSubmitPrim(output.vertices, output.indices, PatchPrimToPrim(surface.primType), output.count, vertTypeID, gstate.getCullMode(), &generatedBytesRead);
|
||||
if (output.count)
|
||||
DispatchSubmitPrim(output.vertices, output.indices, PatchPrimToPrim(surface.primType), output.count, vertTypeID, gstate.getCullMode(), &generatedBytesRead);
|
||||
|
||||
DispatchFlush();
|
||||
|
||||
|
@ -186,14 +186,17 @@ struct Weight2D {
|
||||
};
|
||||
|
||||
struct ControlPoints {
|
||||
Vec3f *pos;
|
||||
Vec2f *tex;
|
||||
Vec4f *col;
|
||||
Vec3f *pos = nullptr;
|
||||
Vec2f *tex = nullptr;
|
||||
Vec4f *col = nullptr;
|
||||
u32_le defcolor;
|
||||
|
||||
ControlPoints() {}
|
||||
ControlPoints(const SimpleVertex *const *points, int size, SimpleBufferManager &managedBuf);
|
||||
void Convert(const SimpleVertex *const *points, int size);
|
||||
bool IsValid() const {
|
||||
return pos && tex && col;
|
||||
}
|
||||
};
|
||||
|
||||
struct OutputBuffers {
|
||||
|
@ -329,6 +329,8 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff) {
|
||||
u32 count = data & 0xFFFF;
|
||||
// Upper bits are ignored.
|
||||
GEPrimitiveType prim = static_cast<GEPrimitiveType>((data >> 16) & 7);
|
||||
if (count == 0)
|
||||
break;
|
||||
|
||||
if (!Memory::IsValidAddress(gstate_c.vertexAddr)) {
|
||||
ERROR_LOG_REPORT(G3D, "Software: Bad vertex address %08x!", gstate_c.vertexAddr);
|
||||
|
Loading…
Reference in New Issue
Block a user