mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-30 19:24:23 +01:00
Improve sanity checks for vertex ranges in GPU
This commit is contained in:
1 parent
dde3099d0c
commit
3e0fea509d
4 files changed
+22
-21
No files matched your search
+11
-15
@@ -1197,8 +1197,10 @@ void GPUCommon::Execute_BoundingBox(u32 op, u32 diff) {
|
||||
// Approximate based on timings of several counts on a PSP.
|
||||
cyclesExecuted += count * 22;
|
||||
|
||||
const bool useInds = (gstate.vertType & GE_VTYPE_IDX_MASK) != 0;
|
||||
VertexDecoder *dec = drawEngineCommon_->GetVertexDecoder(gstate.vertType);
|
||||
const u32 vertType = gstate.vertType;
|
||||
|
||||
const bool useInds = (vertType & GE_VTYPE_IDX_MASK) != 0;
|
||||
const VertexDecoder *dec = drawEngineCommon_->GetVertexDecoder(vertType);
|
||||
int bytesRead = (useInds ? 1 : dec->VertexSize()) * count;
|
||||
|
||||
if (!Memory::IsValidRange(gstate_c.vertexAddr, bytesRead)) {
|
||||
@@ -1207,23 +1209,17 @@ void GPUCommon::Execute_BoundingBox(u32 op, u32 diff) {
|
||||
currentList->bboxResult = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const void *control_points = Memory::GetPointerUnchecked(gstate_c.vertexAddr);
|
||||
if (!control_points) {
|
||||
ERROR_LOG_REPORT_ONCE(boundingbox, Log::G3D, "Invalid verts in bounding box check");
|
||||
currentList->bboxResult = true;
|
||||
return;
|
||||
}
|
||||
const void *control_points = Memory::GetPointerUnchecked(gstate_c.vertexAddr); // we checked the range above.
|
||||
|
||||
const void *inds = nullptr;
|
||||
if (useInds) {
|
||||
int indexShift = ((gstate.vertType & GE_VTYPE_IDX_MASK) >> GE_VTYPE_IDX_SHIFT) - 1;
|
||||
inds = Memory::GetPointerUnchecked(gstate_c.indexAddr);
|
||||
if (!inds || !Memory::IsValidRange(gstate_c.indexAddr, count << indexShift)) {
|
||||
const int indexSizeShift = ((vertType & GE_VTYPE_IDX_MASK) >> GE_VTYPE_IDX_SHIFT) - 1;
|
||||
if (!Memory::IsValidRange(gstate_c.indexAddr, count << indexSizeShift)) {
|
||||
ERROR_LOG_REPORT_ONCE(boundingboxInds, Log::G3D, "Invalid inds in bounding box check");
|
||||
currentList->bboxResult = true;
|
||||
return;
|
||||
}
|
||||
inds = Memory::GetPointerUnchecked(gstate_c.indexAddr);
|
||||
}
|
||||
|
||||
// Test if the bounding box is within the drawing region.
|
||||
@@ -1231,12 +1227,12 @@ void GPUCommon::Execute_BoundingBox(u32 op, u32 diff) {
|
||||
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, inds, 0x100, dec, gstate.vertType);
|
||||
currentList->bboxResult = drawEngineCommon_->TestBoundingBox((const uint8_t *)control_points + skipSize, inds, 0x100, dec, vertType);
|
||||
} else if (count > 0x100) {
|
||||
int checkSize = count - 0x100;
|
||||
currentList->bboxResult = drawEngineCommon_->TestBoundingBox(control_points, inds, checkSize, dec, gstate.vertType);
|
||||
currentList->bboxResult = drawEngineCommon_->TestBoundingBox(control_points, inds, checkSize, dec, vertType);
|
||||
} else {
|
||||
currentList->bboxResult = drawEngineCommon_->TestBoundingBox(control_points, inds, count, dec, gstate.vertType);
|
||||
currentList->bboxResult = drawEngineCommon_->TestBoundingBox(control_points, inds, count, dec, vertType);
|
||||
}
|
||||
AdvanceVerts(gstate.vertType, count, bytesRead);
|
||||
}
|
||||
|
||||
+1
-1
@@ -448,7 +448,7 @@ protected:
|
||||
|
||||
void AdvanceVerts(u32 vertType, int count, int bytesRead) {
|
||||
if ((vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) {
|
||||
int indexShift = ((vertType & GE_VTYPE_IDX_MASK) >> GE_VTYPE_IDX_SHIFT) - 1;
|
||||
const int indexShift = ((vertType & GE_VTYPE_IDX_MASK) >> GE_VTYPE_IDX_SHIFT) - 1;
|
||||
gstate_c.indexAddr += count << indexShift;
|
||||
} else {
|
||||
gstate_c.vertexAddr += bytesRead;
|
||||
|
||||
+10
-4
@@ -985,14 +985,14 @@ void GPUCommonHW::Execute_Prim(u32 op, u32 diff) {
|
||||
const void *verts = Memory::GetPointerUnchecked(gstate_c.vertexAddr);
|
||||
const void *inds = nullptr;
|
||||
|
||||
bool isTriangle = IsTrianglePrim(prim);
|
||||
const bool isTriangle = IsTrianglePrim(prim);
|
||||
|
||||
bool canExtend = isTriangle;
|
||||
u32 vertexType = gstate.vertType;
|
||||
if ((vertexType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) {
|
||||
u32 indexAddr = gstate_c.indexAddr;
|
||||
u32 indexSize = (vertexType & GE_VTYPE_IDX_MASK) >> GE_VTYPE_IDX_SHIFT;
|
||||
if (!Memory::IsValidRange(indexAddr, count * indexSize)) {
|
||||
const int indexShift = ((vertexType & GE_VTYPE_IDX_MASK) >> GE_VTYPE_IDX_SHIFT) - 1;
|
||||
if (!Memory::IsValidRange(indexAddr, count << indexShift)) {
|
||||
ERROR_LOG(Log::G3D, "Bad index address %08x (%d)!", indexAddr, count);
|
||||
return;
|
||||
}
|
||||
@@ -1109,7 +1109,13 @@ void GPUCommonHW::Execute_Prim(u32 op, u32 diff) {
|
||||
verts = Memory::GetPointerUnchecked(gstate_c.vertexAddr);
|
||||
inds = nullptr;
|
||||
if ((vertexType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) {
|
||||
inds = Memory::GetPointerUnchecked(gstate_c.indexAddr);
|
||||
const u32 indexAddr = gstate_c.indexAddr;
|
||||
const int indexShift = ((vertexType & GE_VTYPE_IDX_MASK) >> GE_VTYPE_IDX_SHIFT) - 1;
|
||||
if (!Memory::IsValidRange(gstate_c.indexAddr, count << indexShift)) {
|
||||
// Bad index range. Let's give up the fast loop.
|
||||
goto bail;
|
||||
}
|
||||
inds = Memory::GetPointerUnchecked(indexAddr);
|
||||
} else {
|
||||
// We can extend again after submitting a normal draw.
|
||||
canExtend = isTriangle;
|
||||
|
||||
@@ -420,7 +420,6 @@ struct GPUgstate {
|
||||
int getTransferHeight() const { return ((transfersize >> 10) & 0x3FF) + 1; }
|
||||
int getTransferBpp() const { return (transferstart & 1) ? 4 : 2; }
|
||||
|
||||
|
||||
void FastLoadBoneMatrix(u32 addr);
|
||||
|
||||
// Real data in the context ends here
|
||||
|
||||
Reference in new issue
Block a user