Bounds check writing to the index buffer when expanding lines/rects/points
This commit is contained in:
parent
f40f7ed38c
commit
14f9c27b4e
6 changed files with 53 additions and 20 deletions
|
@ -547,7 +547,7 @@ void SoftwareTransform::DetectOffsetTexture(int maxIndex) {
|
|||
}
|
||||
|
||||
// NOTE: The viewport must be up to date!
|
||||
void SoftwareTransform::BuildDrawingParams(int prim, int vertexCount, u32 vertType, u16 *inds, int &indsOffset, int &maxIndex, SoftwareTransformResult *result) {
|
||||
void SoftwareTransform::BuildDrawingParams(int prim, int vertexCount, u32 vertType, u16 *inds, int &indsOffset, int indexBufferSize, int &maxIndex, SoftwareTransformResult *result) {
|
||||
TransformedVertex *transformed = params_.transformed;
|
||||
TransformedVertex *transformedExpanded = params_.transformedExpanded;
|
||||
bool throughmode = (vertType & GE_VTYPE_THROUGH_MASK) != 0;
|
||||
|
@ -560,7 +560,11 @@ void SoftwareTransform::BuildDrawingParams(int prim, int vertexCount, u32 vertTy
|
|||
bool useBufferedRendering = fbman->UseBufferedRendering();
|
||||
|
||||
if (prim == GE_PRIM_RECTANGLES) {
|
||||
ExpandRectangles(vertexCount, maxIndex, inds, indsOffset, transformed, transformedExpanded, numTrans, throughmode);
|
||||
if (!ExpandRectangles(vertexCount, maxIndex, inds, indsOffset, indexBufferSize, transformed, transformedExpanded, numTrans, throughmode)) {
|
||||
result->drawIndexed = false;
|
||||
result->drawNumTrans = 0;
|
||||
return;
|
||||
}
|
||||
result->drawBuffer = transformedExpanded;
|
||||
result->drawIndexed = true;
|
||||
|
||||
|
@ -578,11 +582,19 @@ void SoftwareTransform::BuildDrawingParams(int prim, int vertexCount, u32 vertTy
|
|||
}
|
||||
}
|
||||
} else if (prim == GE_PRIM_POINTS) {
|
||||
ExpandPoints(vertexCount, maxIndex, inds, indsOffset, transformed, transformedExpanded, numTrans, throughmode);
|
||||
if (!ExpandPoints(vertexCount, maxIndex, inds, indsOffset, indexBufferSize, transformed, transformedExpanded, numTrans, throughmode)) {
|
||||
result->drawIndexed = false;
|
||||
result->drawNumTrans = 0;
|
||||
return;
|
||||
}
|
||||
result->drawBuffer = transformedExpanded;
|
||||
result->drawIndexed = true;
|
||||
} else if (prim == GE_PRIM_LINES) {
|
||||
ExpandLines(vertexCount, maxIndex, inds, indsOffset, transformed, transformedExpanded, numTrans, throughmode);
|
||||
if (!ExpandLines(vertexCount, maxIndex, inds, indsOffset, indexBufferSize, transformed, transformedExpanded, numTrans, throughmode)) {
|
||||
result->drawIndexed = false;
|
||||
result->drawNumTrans = 0;
|
||||
return;
|
||||
}
|
||||
result->drawBuffer = transformedExpanded;
|
||||
result->drawIndexed = true;
|
||||
} else {
|
||||
|
@ -674,7 +686,13 @@ void SoftwareTransform::CalcCullParams(float &minZValue, float &maxZValue) {
|
|||
std::swap(minZValue, maxZValue);
|
||||
}
|
||||
|
||||
void SoftwareTransform::ExpandRectangles(int vertexCount, int &maxIndex, u16 *inds, int &indsOffset, const TransformedVertex *transformed, TransformedVertex *transformedExpanded, int &numTrans, bool throughmode) {
|
||||
bool SoftwareTransform::ExpandRectangles(int vertexCount, int &maxIndex, u16 *inds, int &indsOffset, int indexBufferSize, const TransformedVertex *transformed, TransformedVertex *transformedExpanded, int &numTrans, bool throughmode) {
|
||||
// Before we start, do a sanity check - does the output fit?
|
||||
if ((vertexCount / 2) * 6 > indexBufferSize - indsOffset) {
|
||||
// Won't fit, kill the draw.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Rectangles always need 2 vertices, disregard the last one if there's an odd number.
|
||||
vertexCount = vertexCount & ~1;
|
||||
numTrans = 0;
|
||||
|
@ -735,9 +753,16 @@ void SoftwareTransform::ExpandRectangles(int vertexCount, int &maxIndex, u16 *in
|
|||
}
|
||||
|
||||
indsOffset = newIndsOffset;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SoftwareTransform::ExpandLines(int vertexCount, int &maxIndex, u16 *inds, int &indsOffset, const TransformedVertex *transformed, TransformedVertex *transformedExpanded, int &numTrans, bool throughmode) {
|
||||
bool SoftwareTransform::ExpandLines(int vertexCount, int &maxIndex, u16 *inds, int &indsOffset, int indexBufferSize, const TransformedVertex *transformed, TransformedVertex *transformedExpanded, int &numTrans, bool throughmode) {
|
||||
// Before we start, do a sanity check - does the output fit?
|
||||
if ((vertexCount / 2) * 6 > indexBufferSize - indsOffset) {
|
||||
// Won't fit, kill the draw.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Lines always need 2 vertices, disregard the last one if there's an odd number.
|
||||
vertexCount = vertexCount & ~1;
|
||||
numTrans = 0;
|
||||
|
@ -860,9 +885,16 @@ void SoftwareTransform::ExpandLines(int vertexCount, int &maxIndex, u16 *inds, i
|
|||
}
|
||||
|
||||
indsOffset = newIndsOffset;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SoftwareTransform::ExpandPoints(int vertexCount, int &maxIndex, u16 *inds, int &indsOffset, const TransformedVertex *transformed, TransformedVertex *transformedExpanded, int &numTrans, bool throughmode) {
|
||||
bool SoftwareTransform::ExpandPoints(int vertexCount, int &maxIndex, u16 *inds, int &indsOffset, int indexBufferSize, const TransformedVertex *transformed, TransformedVertex *transformedExpanded, int &numTrans, bool throughmode) {
|
||||
// Before we start, do a sanity check - does the output fit?
|
||||
if (vertexCount * 6 > indexBufferSize - indsOffset) {
|
||||
// Won't fit, kill the draw.
|
||||
return false;
|
||||
}
|
||||
|
||||
numTrans = 0;
|
||||
TransformedVertex *trans = &transformedExpanded[0];
|
||||
|
||||
|
@ -929,4 +961,5 @@ void SoftwareTransform::ExpandPoints(int vertexCount, int &maxIndex, u16 *inds,
|
|||
}
|
||||
|
||||
indsOffset = newIndsOffset;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -67,13 +67,13 @@ public:
|
|||
void SetProjMatrix(const float mtx[14], bool invertedX, bool invertedY, const Lin::Vec3 &trans, const Lin::Vec3 &scale);
|
||||
void Decode(int prim, u32 vertexType, const DecVtxFormat &decVtxFormat, int maxIndex, SoftwareTransformResult *result);
|
||||
void DetectOffsetTexture(int maxIndex);
|
||||
void BuildDrawingParams(int prim, int vertexCount, u32 vertType, u16 *inds, int &indsOffset, int &maxIndex, SoftwareTransformResult *result);
|
||||
void BuildDrawingParams(int prim, int vertexCount, u32 vertType, u16 *inds, int &indsOffset, int indexBufferSize, int &maxIndex, SoftwareTransformResult *result);
|
||||
|
||||
protected:
|
||||
void CalcCullParams(float &minZValue, float &maxZValue);
|
||||
void ExpandRectangles(int vertexCount, int &maxIndex, u16 *inds, int &indsOffset, const TransformedVertex *transformed, TransformedVertex *transformedExpanded, int &numTrans, bool throughmode);
|
||||
void ExpandLines(int vertexCount, int &maxIndex, u16 *inds, int &indsOffset, const TransformedVertex *transformed, TransformedVertex *transformedExpanded, int &numTrans, bool throughmode);
|
||||
void ExpandPoints(int vertexCount, int &maxIndex, u16 *inds, int &indsOffset, const TransformedVertex *transformed, TransformedVertex *transformedExpanded, int &numTrans, bool throughmode);
|
||||
bool ExpandRectangles(int vertexCount, int &maxIndex, u16 *inds, int &indsOffset, int indexBufferSize, const TransformedVertex *transformed, TransformedVertex *transformedExpanded, int &numTrans, bool throughmode);
|
||||
bool ExpandLines(int vertexCount, int &maxIndex, u16 *inds, int &indsOffset, int indexBufferSize, const TransformedVertex *transformed, TransformedVertex *transformedExpanded, int &numTrans, bool throughmode);
|
||||
bool ExpandPoints(int vertexCount, int &maxIndex, u16 *inds, int &indsOffset, int indexBufferSize, const TransformedVertex *transformed, TransformedVertex *transformedExpanded, int &numTrans, bool throughmode);
|
||||
|
||||
const SoftwareTransformParams ¶ms_;
|
||||
Lin::Matrix4x4 projMatrix_;
|
||||
|
|
|
@ -643,7 +643,7 @@ rotateVBO:
|
|||
|
||||
int indsOffset = 0;
|
||||
if (result.action == SW_NOT_READY)
|
||||
swTransform.BuildDrawingParams(prim, indexGen.VertexCount(), dec_->VertexType(), inds, indsOffset, maxIndex, &result);
|
||||
swTransform.BuildDrawingParams(prim, indexGen.VertexCount(), dec_->VertexType(), inds, indsOffset, DECODED_INDEX_BUFFER_SIZE / sizeof(uint16_t), maxIndex, &result);
|
||||
if (result.setSafeSize)
|
||||
framebufferManager_->SetSafeSize(result.safeWidth, result.safeHeight);
|
||||
|
||||
|
@ -681,11 +681,11 @@ rotateVBO:
|
|||
UINT iOffset;
|
||||
int iSize = sizeof(uint16_t) * result.drawNumTrans;
|
||||
uint8_t *iptr = pushInds_->BeginPush(context_, &iOffset, iSize);
|
||||
memcpy(iptr, inds, iSize);
|
||||
memcpy(iptr, inds + indsOffset, iSize);
|
||||
pushInds_->EndPush(context_);
|
||||
context_->IASetIndexBuffer(pushInds_->Buf(), DXGI_FORMAT_R16_UINT, iOffset);
|
||||
context_->DrawIndexed(result.drawNumTrans, 0, 0);
|
||||
} else {
|
||||
} else if (result.drawNumTrans > 0) {
|
||||
context_->Draw(result.drawNumTrans, 0);
|
||||
}
|
||||
} else if (result.action == SW_CLEAR) {
|
||||
|
|
|
@ -609,7 +609,7 @@ rotateVBO:
|
|||
|
||||
int indsOffset = 0;
|
||||
if (result.action == SW_NOT_READY)
|
||||
swTransform.BuildDrawingParams(prim, indexGen.VertexCount(), dec_->VertexType(), inds, indsOffset, maxIndex, &result);
|
||||
swTransform.BuildDrawingParams(prim, indexGen.VertexCount(), dec_->VertexType(), inds, indsOffset, DECODED_INDEX_BUFFER_SIZE / sizeof(uint16_t), maxIndex, &result);
|
||||
if (result.setSafeSize)
|
||||
framebufferManager_->SetSafeSize(result.safeWidth, result.safeHeight);
|
||||
|
||||
|
@ -630,7 +630,7 @@ rotateVBO:
|
|||
device_->SetVertexDeclaration(transformedVertexDecl_);
|
||||
if (result.drawIndexed) {
|
||||
device_->DrawIndexedPrimitiveUP(d3d_prim[prim], 0, maxIndex, D3DPrimCount(d3d_prim[prim], result.drawNumTrans), inds + indsOffset, D3DFMT_INDEX16, result.drawBuffer, sizeof(TransformedVertex));
|
||||
} else {
|
||||
} else if (result.drawNumTrans > 0) {
|
||||
device_->DrawPrimitiveUP(d3d_prim[prim], D3DPrimCount(d3d_prim[prim], result.drawNumTrans), result.drawBuffer, sizeof(TransformedVertex));
|
||||
}
|
||||
} else if (result.action == SW_CLEAR) {
|
||||
|
|
|
@ -409,7 +409,7 @@ void DrawEngineGLES::DoFlush() {
|
|||
|
||||
int indsOffset = 0;
|
||||
if (result.action == SW_NOT_READY)
|
||||
swTransform.BuildDrawingParams(prim, vertexCount, dec_->VertexType(), inds, indsOffset, maxIndex, &result);
|
||||
swTransform.BuildDrawingParams(prim, vertexCount, dec_->VertexType(), inds, indsOffset, DECODED_INDEX_BUFFER_SIZE / sizeof(uint16_t), maxIndex, &result);
|
||||
if (result.setSafeSize)
|
||||
framebufferManager_->SetSafeSize(result.safeWidth, result.safeHeight);
|
||||
|
||||
|
@ -428,7 +428,7 @@ void DrawEngineGLES::DoFlush() {
|
|||
render_->BindVertexBuffer(softwareInputLayout_, vertexBuffer, vertexBufferOffset);
|
||||
render_->BindIndexBuffer(indexBuffer);
|
||||
render_->DrawIndexed(glprim[prim], result.drawNumTrans, GL_UNSIGNED_SHORT, (void *)(intptr_t)indexBufferOffset);
|
||||
} else {
|
||||
} else if (result.drawNumTrans > 0) {
|
||||
vertexBufferOffset = (uint32_t)frameData.pushVertex->Push(result.drawBuffer, result.drawNumTrans * sizeof(TransformedVertex), &vertexBuffer);
|
||||
render_->BindVertexBuffer(softwareInputLayout_, vertexBuffer, vertexBufferOffset);
|
||||
render_->Draw(glprim[prim], 0, result.drawNumTrans);
|
||||
|
|
|
@ -898,7 +898,7 @@ void DrawEngineVulkan::DoFlush() {
|
|||
int indsOffset = 0;
|
||||
if (result.action == SW_NOT_READY) {
|
||||
swTransform.DetectOffsetTexture(maxIndex);
|
||||
swTransform.BuildDrawingParams(prim, indexGen.VertexCount(), dec_->VertexType(), inds, indsOffset, maxIndex, &result);
|
||||
swTransform.BuildDrawingParams(prim, indexGen.VertexCount(), dec_->VertexType(), inds, indsOffset, DECODED_INDEX_BUFFER_SIZE / sizeof(uint16_t), maxIndex, &result);
|
||||
}
|
||||
|
||||
if (result.setSafeSize)
|
||||
|
@ -970,7 +970,7 @@ void DrawEngineVulkan::DoFlush() {
|
|||
vbOffset = (uint32_t)pushVertex_->Push(result.drawBuffer, maxIndex * sizeof(TransformedVertex), 4, &vbuf);
|
||||
ibOffset = (uint32_t)pushIndex_->Push(inds + indsOffset, sizeof(short) * result.drawNumTrans, 4, &ibuf);
|
||||
renderManager->DrawIndexed(ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, result.drawNumTrans, 1, VK_INDEX_TYPE_UINT16);
|
||||
} else {
|
||||
} else if (result.drawNumTrans > 0) {
|
||||
VkBuffer vbuf;
|
||||
vbOffset = (uint32_t)pushVertex_->Push(result.drawBuffer, result.drawNumTrans * sizeof(TransformedVertex), 4, &vbuf);
|
||||
renderManager->Draw(ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, result.drawNumTrans);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue