mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-24 00:29:57 +00:00
Add support for 32-bit indices.
Not clear how often these are used by games. Let's find out.
This commit is contained in:
parent
d85dce0c21
commit
1e0051a792
@ -201,23 +201,32 @@ bool DrawEngineCommon::GetCurrentSimpleVertices(int count, std::vector<GPUDebugV
|
||||
if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) {
|
||||
const u8 *inds = Memory::GetPointer(gstate_c.indexAddr);
|
||||
const u16 *inds16 = (const u16 *)inds;
|
||||
const u32 *inds32 = (const u32 *)inds;
|
||||
|
||||
if (inds) {
|
||||
GetIndexBounds(inds, count, gstate.vertType, &indexLowerBound, &indexUpperBound);
|
||||
indices.resize(count);
|
||||
switch (gstate.vertType & GE_VTYPE_IDX_MASK) {
|
||||
case GE_VTYPE_IDX_16BIT:
|
||||
for (int i = 0; i < count; ++i) {
|
||||
indices[i] = inds16[i];
|
||||
}
|
||||
break;
|
||||
case GE_VTYPE_IDX_8BIT:
|
||||
for (int i = 0; i < count; ++i) {
|
||||
indices[i] = inds[i];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
case GE_VTYPE_IDX_16BIT:
|
||||
for (int i = 0; i < count; ++i) {
|
||||
indices[i] = inds16[i];
|
||||
}
|
||||
break;
|
||||
case GE_VTYPE_IDX_32BIT:
|
||||
WARN_LOG_REPORT_ONCE(simpleIndexes32, G3D, "SimpleVertices: Decoding 32-bit indexes");
|
||||
for (int i = 0; i < count; ++i) {
|
||||
// These aren't documented and should be rare. Let's bounds check each one.
|
||||
if (inds32[i] != (u16)inds32[i]) {
|
||||
ERROR_LOG_REPORT_ONCE(simpleIndexes32Bounds, G3D, "SimpleVertices: Index outside 16-bit range");
|
||||
}
|
||||
indices[i] = (u16)inds32[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
indices.clear();
|
||||
|
@ -62,6 +62,16 @@ protected:
|
||||
|
||||
VertexDecoder *GetVertexDecoder(u32 vtype);
|
||||
|
||||
inline int IndexSize(u32 vtype) const {
|
||||
const u32 indexType = (vtype & GE_VTYPE_IDX_MASK);
|
||||
if (indexType == GE_VTYPE_IDX_16BIT) {
|
||||
return 2;
|
||||
} else if (indexType == GE_VTYPE_IDX_32BIT) {
|
||||
return 4;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Vertex collector buffers
|
||||
u8 *decoded;
|
||||
u16 *decIndex;
|
||||
|
@ -112,7 +112,7 @@ void IndexGenerator::AddStrip(int numVerts) {
|
||||
inds_ = outInds;
|
||||
index_ += numVerts;
|
||||
if (numTris > 0)
|
||||
count_ += numTris * 3;
|
||||
count_ += numTris * 3;
|
||||
// This is so we can detect one single strip by just looking at seenPrims_.
|
||||
if (!seenPrims_) {
|
||||
seenPrims_ = 1 << GE_PRIM_TRIANGLE_STRIP;
|
||||
@ -187,10 +187,9 @@ void IndexGenerator::AddRectangles(int numVerts) {
|
||||
seenPrims_ |= 1 << GE_PRIM_RECTANGLES;
|
||||
}
|
||||
|
||||
template <class IType, class ITypeLE, int flag>
|
||||
void IndexGenerator::TranslatePoints(int numInds, const IType *_inds, int indexOffset) {
|
||||
template <class ITypeLE, int flag>
|
||||
void IndexGenerator::TranslatePoints(int numInds, const ITypeLE *inds, int indexOffset) {
|
||||
indexOffset = index_ - indexOffset;
|
||||
const ITypeLE *inds = (const IType *)_inds;
|
||||
u16 *outInds = inds_;
|
||||
for (int i = 0; i < numInds; i++)
|
||||
*outInds++ = indexOffset + inds[i];
|
||||
@ -200,10 +199,9 @@ void IndexGenerator::TranslatePoints(int numInds, const IType *_inds, int indexO
|
||||
seenPrims_ |= (1 << GE_PRIM_POINTS) | flag;
|
||||
}
|
||||
|
||||
template <class IType, class ITypeLE, int flag>
|
||||
void IndexGenerator::TranslateLineList(int numInds, const IType *_inds, int indexOffset) {
|
||||
template <class ITypeLE, int flag>
|
||||
void IndexGenerator::TranslateLineList(int numInds, const ITypeLE *inds, int indexOffset) {
|
||||
indexOffset = index_ - indexOffset;
|
||||
const ITypeLE *inds = (ITypeLE*)_inds;
|
||||
u16 *outInds = inds_;
|
||||
numInds = numInds & ~1;
|
||||
for (int i = 0; i < numInds; i += 2) {
|
||||
@ -216,10 +214,9 @@ void IndexGenerator::TranslateLineList(int numInds, const IType *_inds, int inde
|
||||
seenPrims_ |= (1 << GE_PRIM_LINES) | flag;
|
||||
}
|
||||
|
||||
template <class IType, class ITypeLE, int flag>
|
||||
void IndexGenerator::TranslateLineStrip(int numInds, const IType *_inds, int indexOffset) {
|
||||
template <class ITypeLE, int flag>
|
||||
void IndexGenerator::TranslateLineStrip(int numInds, const ITypeLE *inds, int indexOffset) {
|
||||
indexOffset = index_ - indexOffset;
|
||||
const ITypeLE *inds = (const ITypeLE*)_inds;
|
||||
int numLines = numInds - 1;
|
||||
u16 *outInds = inds_;
|
||||
for (int i = 0; i < numLines; i++) {
|
||||
@ -232,9 +229,8 @@ void IndexGenerator::TranslateLineStrip(int numInds, const IType *_inds, int ind
|
||||
seenPrims_ |= (1 << GE_PRIM_LINE_STRIP) | flag;
|
||||
}
|
||||
|
||||
template <class IType, class ITypeLE, int flag>
|
||||
void IndexGenerator::TranslateList(int numInds, const IType *_inds, int indexOffset) {
|
||||
const ITypeLE *inds = (const IType *)_inds;
|
||||
template <class ITypeLE, int flag>
|
||||
void IndexGenerator::TranslateList(int numInds, const ITypeLE *inds, int indexOffset) {
|
||||
indexOffset = index_ - indexOffset;
|
||||
u16 *outInds = inds_;
|
||||
int numTris = numInds / 3; // Round to whole triangles
|
||||
@ -250,9 +246,8 @@ void IndexGenerator::TranslateList(int numInds, const IType *_inds, int indexOff
|
||||
seenPrims_ |= (1 << GE_PRIM_TRIANGLES) | flag;
|
||||
}
|
||||
|
||||
template <class IType, class ITypeLE, int flag>
|
||||
void IndexGenerator::TranslateStrip(int numInds, const IType *_inds, int indexOffset) {
|
||||
const IType *inds = (ITypeLE*)_inds;
|
||||
template <class ITypeLE, int flag>
|
||||
void IndexGenerator::TranslateStrip(int numInds, const ITypeLE *inds, int indexOffset) {
|
||||
int wind = 1;
|
||||
indexOffset = index_ - indexOffset;
|
||||
int numTris = numInds - 2;
|
||||
@ -269,9 +264,8 @@ void IndexGenerator::TranslateStrip(int numInds, const IType *_inds, int indexOf
|
||||
seenPrims_ |= (1 << GE_PRIM_TRIANGLE_STRIP) | flag;
|
||||
}
|
||||
|
||||
template <class IType, class ITypeLE, int flag>
|
||||
void IndexGenerator::TranslateFan(int numInds, const IType *_inds, int indexOffset) {
|
||||
const ITypeLE *inds = (IType*)_inds;
|
||||
template <class ITypeLE, int flag>
|
||||
void IndexGenerator::TranslateFan(int numInds, const ITypeLE *inds, int indexOffset) {
|
||||
if (numInds <= 0) return;
|
||||
indexOffset = index_ - indexOffset;
|
||||
int numTris = numInds - 2;
|
||||
@ -287,10 +281,9 @@ void IndexGenerator::TranslateFan(int numInds, const IType *_inds, int indexOffs
|
||||
seenPrims_ |= (1 << GE_PRIM_TRIANGLE_FAN) | flag;
|
||||
}
|
||||
|
||||
template <class IType, class ITypeLE, int flag>
|
||||
inline void IndexGenerator::TranslateRectangles(int numInds, const IType *_inds, int indexOffset) {
|
||||
template <class ITypeLE, int flag>
|
||||
inline void IndexGenerator::TranslateRectangles(int numInds, const ITypeLE *inds, int indexOffset) {
|
||||
indexOffset = index_ - indexOffset;
|
||||
const ITypeLE *inds = (const ITypeLE*)_inds;
|
||||
u16 *outInds = inds_;
|
||||
//rectangles always need 2 vertices, disregard the last one if there's an odd number
|
||||
numInds = numInds & ~1;
|
||||
@ -307,36 +300,36 @@ inline void IndexGenerator::TranslateRectangles(int numInds, const IType *_inds,
|
||||
// Could template this too, but would have to define in header.
|
||||
void IndexGenerator::TranslatePrim(int prim, int numInds, const u8 *inds, int indexOffset) {
|
||||
switch (prim) {
|
||||
case GE_PRIM_POINTS: TranslatePoints<u8, u8, SEEN_INDEX16>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_LINES: TranslateLineList<u8, u8, SEEN_INDEX16>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_LINE_STRIP: TranslateLineStrip<u8, u8, SEEN_INDEX16>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_TRIANGLES: TranslateList<u8, u8, SEEN_INDEX16>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_TRIANGLE_STRIP: TranslateStrip<u8, u8, SEEN_INDEX16>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_TRIANGLE_FAN: TranslateFan<u8, u8, SEEN_INDEX16>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_RECTANGLES: TranslateRectangles<u8, u8, SEEN_INDEX16>(numInds, inds, indexOffset); break; // Same
|
||||
case GE_PRIM_POINTS: TranslatePoints<u8, SEEN_INDEX8>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_LINES: TranslateLineList<u8, SEEN_INDEX8>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_LINE_STRIP: TranslateLineStrip<u8, SEEN_INDEX8>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_TRIANGLES: TranslateList<u8, SEEN_INDEX8>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_TRIANGLE_STRIP: TranslateStrip<u8, SEEN_INDEX8>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_TRIANGLE_FAN: TranslateFan<u8, SEEN_INDEX8>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_RECTANGLES: TranslateRectangles<u8, SEEN_INDEX8>(numInds, inds, indexOffset); break; // Same
|
||||
}
|
||||
}
|
||||
|
||||
void IndexGenerator::TranslatePrim(int prim, int numInds, const u16 *inds, int indexOffset) {
|
||||
switch (prim) {
|
||||
case GE_PRIM_POINTS: TranslatePoints<u16, u16_le, SEEN_INDEX16>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_LINES: TranslateLineList<u16, u16_le, SEEN_INDEX16>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_LINE_STRIP: TranslateLineStrip<u16, u16_le, SEEN_INDEX16>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_TRIANGLES: TranslateList<u16, u16_le, SEEN_INDEX16>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_TRIANGLE_STRIP: TranslateStrip<u16, u16_le, SEEN_INDEX16>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_TRIANGLE_FAN: TranslateFan<u16, u16_le, SEEN_INDEX16>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_RECTANGLES: TranslateRectangles<u16, u16_le, SEEN_INDEX16>(numInds, inds, indexOffset); break; // Same
|
||||
case GE_PRIM_POINTS: TranslatePoints<u16_le, SEEN_INDEX16>(numInds, (const u16_le *)inds, indexOffset); break;
|
||||
case GE_PRIM_LINES: TranslateLineList<u16_le, SEEN_INDEX16>(numInds, (const u16_le *)inds, indexOffset); break;
|
||||
case GE_PRIM_LINE_STRIP: TranslateLineStrip<u16_le, SEEN_INDEX16>(numInds, (const u16_le *)inds, indexOffset); break;
|
||||
case GE_PRIM_TRIANGLES: TranslateList<u16_le, SEEN_INDEX16>(numInds, (const u16_le *)inds, indexOffset); break;
|
||||
case GE_PRIM_TRIANGLE_STRIP: TranslateStrip<u16_le, SEEN_INDEX16>(numInds, (const u16_le *)inds, indexOffset); break;
|
||||
case GE_PRIM_TRIANGLE_FAN: TranslateFan<u16_le, SEEN_INDEX16>(numInds, (const u16_le *)inds, indexOffset); break;
|
||||
case GE_PRIM_RECTANGLES: TranslateRectangles<u16_le, SEEN_INDEX16>(numInds, (const u16_le *)inds, indexOffset); break; // Same
|
||||
}
|
||||
}
|
||||
|
||||
void IndexGenerator::TranslatePrim(int prim, int numInds, const u32 *inds, int indexOffset) {
|
||||
switch (prim) {
|
||||
case GE_PRIM_POINTS: TranslatePoints<u32, u32_le, SEEN_INDEX16>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_LINES: TranslateLineList<u32, u32_le, SEEN_INDEX16>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_LINE_STRIP: TranslateLineStrip<u32, u32_le, SEEN_INDEX16>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_TRIANGLES: TranslateList<u32, u32_le, SEEN_INDEX16>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_TRIANGLE_STRIP: TranslateStrip<u32, u32_le, SEEN_INDEX16>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_TRIANGLE_FAN: TranslateFan<u32, u32_le, SEEN_INDEX16>(numInds, inds, indexOffset); break;
|
||||
case GE_PRIM_RECTANGLES: TranslateRectangles<u32, u32_le, SEEN_INDEX16>(numInds, inds, indexOffset); break; // Same
|
||||
case GE_PRIM_POINTS: TranslatePoints<u32_le, SEEN_INDEX32>(numInds, (const u32_le *)inds, indexOffset); break;
|
||||
case GE_PRIM_LINES: TranslateLineList<u32_le, SEEN_INDEX32>(numInds, (const u32_le *)inds, indexOffset); break;
|
||||
case GE_PRIM_LINE_STRIP: TranslateLineStrip<u32_le, SEEN_INDEX32>(numInds, (const u32_le *)inds, indexOffset); break;
|
||||
case GE_PRIM_TRIANGLES: TranslateList<u32_le, SEEN_INDEX32>(numInds, (const u32_le *)inds, indexOffset); break;
|
||||
case GE_PRIM_TRIANGLE_STRIP: TranslateStrip<u32_le, SEEN_INDEX32>(numInds, (const u32_le *)inds, indexOffset); break;
|
||||
case GE_PRIM_TRIANGLE_FAN: TranslateFan<u32_le, SEEN_INDEX32>(numInds, (const u32_le *)inds, indexOffset); break;
|
||||
case GE_PRIM_RECTANGLES: TranslateRectangles<u32_le, SEEN_INDEX32>(numInds, (const u32_le *)inds, indexOffset); break; // Same
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,26 +66,27 @@ private:
|
||||
void AddRectangles(int numVerts);
|
||||
|
||||
// These translate already indexed lists
|
||||
template <class IType, class ITypeLE, int flag>
|
||||
void TranslatePoints(int numVerts, const IType *inds, int indexOffset);
|
||||
template <class IType, class ITypeLE, int flag>
|
||||
void TranslateList(int numVerts, const IType *_inds, int indexOffset);
|
||||
template <class IType, class ITypeLE, int flag>
|
||||
inline void TranslateLineList(int numVerts, const IType *inds, int indexOffset);
|
||||
template <class IType, class ITypeLE, int flag>
|
||||
inline void TranslateLineStrip(int numVerts, const IType *inds, int indexOffset);
|
||||
template <class ITypeLE, int flag>
|
||||
void TranslatePoints(int numVerts, const ITypeLE *inds, int indexOffset);
|
||||
template <class ITypeLE, int flag>
|
||||
void TranslateList(int numVerts, const ITypeLE *inds, int indexOffset);
|
||||
template <class ITypeLE, int flag>
|
||||
inline void TranslateLineList(int numVerts, const ITypeLE *inds, int indexOffset);
|
||||
template <class ITypeLE, int flag>
|
||||
inline void TranslateLineStrip(int numVerts, const ITypeLE *inds, int indexOffset);
|
||||
|
||||
template <class IType, class ITypeLE, int flag>
|
||||
void TranslateStrip(int numVerts, const IType *inds, int indexOffset);
|
||||
template <class IType, class ITypeLE, int flag>
|
||||
void TranslateFan(int numVerts, const IType *inds, int indexOffset);
|
||||
template <class ITypeLE, int flag>
|
||||
void TranslateStrip(int numVerts, const ITypeLE *inds, int indexOffset);
|
||||
template <class ITypeLE, int flag>
|
||||
void TranslateFan(int numVerts, const ITypeLE *inds, int indexOffset);
|
||||
|
||||
template <class IType, class ITypeLE, int flag>
|
||||
inline void TranslateRectangles(int numVerts, const IType *inds, int indexOffset);
|
||||
template <class ITypeLE, int flag>
|
||||
inline void TranslateRectangles(int numVerts, const ITypeLE *inds, int indexOffset);
|
||||
|
||||
enum {
|
||||
SEEN_INDEX8 = 1 << 16,
|
||||
SEEN_INDEX16 = 1 << 17
|
||||
SEEN_INDEX16 = 1 << 17,
|
||||
SEEN_INDEX32 = 1 << 18,
|
||||
};
|
||||
|
||||
u16 *indsBase_;
|
||||
|
@ -791,10 +791,12 @@ void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indi
|
||||
u16 index_lower_bound = 0;
|
||||
u16 index_upper_bound = count_u * count_v - 1;
|
||||
bool indices_16bit = (vertType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT;
|
||||
const u8* indices8 = (const u8*)indices;
|
||||
const u16* indices16 = (const u16*)indices;
|
||||
bool indices_32bit = (vertType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_32BIT;
|
||||
const u8 *indices8 = (const u8 *)indices;
|
||||
const u16 *indices16 = (const u16 *)indices;
|
||||
const u32 *indices32 = (const u32 *)indices;
|
||||
if (indices)
|
||||
GetIndexBounds(indices, count_u*count_v, vertType, &index_lower_bound, &index_upper_bound);
|
||||
GetIndexBounds(indices, count_u * count_v, vertType, &index_lower_bound, &index_upper_bound);
|
||||
|
||||
// Simplify away bones and morph before proceeding
|
||||
SimpleVertex *simplified_control_points = (SimpleVertex *)(decoded + 65536 * 12);
|
||||
@ -815,10 +817,19 @@ void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indi
|
||||
|
||||
// Make an array of pointers to the control points, to get rid of indices.
|
||||
for (int idx = 0; idx < count_u * count_v; idx++) {
|
||||
if (indices)
|
||||
points[idx] = simplified_control_points + (indices_16bit ? indices16[idx] : indices8[idx]);
|
||||
else
|
||||
if (indices) {
|
||||
u32 ind;
|
||||
if (indices_32bit) {
|
||||
ind = indices32[idx];
|
||||
} else if (indices_16bit) {
|
||||
ind = indices16[idx];
|
||||
} else {
|
||||
ind = indices8[idx];
|
||||
}
|
||||
points[idx] = simplified_control_points + ind;
|
||||
} else {
|
||||
points[idx] = simplified_control_points + idx;
|
||||
}
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
@ -876,8 +887,10 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi
|
||||
u16 index_lower_bound = 0;
|
||||
u16 index_upper_bound = count_u * count_v - 1;
|
||||
bool indices_16bit = (vertType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT;
|
||||
const u8* indices8 = (const u8*)indices;
|
||||
const u16* indices16 = (const u16*)indices;
|
||||
bool indices_32bit = (vertType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_32BIT;
|
||||
const u8 *indices8 = (const u8 *)indices;
|
||||
const u16 *indices16 = (const u16 *)indices;
|
||||
const u32 *indices32 = (const u32 *)indices;
|
||||
if (indices)
|
||||
GetIndexBounds(indices, count_u*count_v, vertType, &index_lower_bound, &index_upper_bound);
|
||||
|
||||
@ -905,10 +918,19 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi
|
||||
BezierPatch& patch = patches[patch_u + patch_v * num_patches_u];
|
||||
for (int point = 0; point < 16; ++point) {
|
||||
int idx = (patch_u * 3 + point % 4) + (patch_v * 3 + point / 4) * count_u;
|
||||
if (indices)
|
||||
patch.points[point] = simplified_control_points + (indices_16bit ? indices16[idx] : indices8[idx]);
|
||||
else
|
||||
if (indices) {
|
||||
u32 ind;
|
||||
if (indices_32bit) {
|
||||
ind = indices32[idx];
|
||||
} else if (indices_16bit) {
|
||||
ind = indices16[idx];
|
||||
} else {
|
||||
ind = indices8[idx];
|
||||
}
|
||||
patch.points[point] = simplified_control_points + ind;
|
||||
} else {
|
||||
patch.points[point] = simplified_control_points + idx;
|
||||
}
|
||||
}
|
||||
patch.u_index = patch_u * 3;
|
||||
patch.v_index = patch_v * 3;
|
||||
|
@ -95,7 +95,7 @@ void GetIndexBounds(const void *inds, int count, u32 vertType, u16 *indexLowerBo
|
||||
lowerBound = value;
|
||||
}
|
||||
} else if (idx == GE_VTYPE_IDX_16BIT) {
|
||||
const u16 *ind16 = (const u16*)inds;
|
||||
const u16 *ind16 = (const u16 *)inds;
|
||||
for (int i = 0; i < count; i++) {
|
||||
u16 value = ind16[i];
|
||||
if (value > upperBound)
|
||||
@ -103,6 +103,20 @@ void GetIndexBounds(const void *inds, int count, u32 vertType, u16 *indexLowerBo
|
||||
if (value < lowerBound)
|
||||
lowerBound = value;
|
||||
}
|
||||
} else if (idx == GE_VTYPE_IDX_32BIT) {
|
||||
WARN_LOG_REPORT_ONCE(indexBounds32, G3D, "GetIndexBounds: Decoding 32-bit indexes");
|
||||
const u32 *ind32 = (const u32 *)inds;
|
||||
for (int i = 0; i < count; i++) {
|
||||
u16 value = (u16)ind32[i];
|
||||
// These aren't documented and should be rare. Let's bounds check each one.
|
||||
if (ind32[i] != value) {
|
||||
ERROR_LOG_REPORT_ONCE(indexBounds32Bounds, G3D, "GetIndexBounds: Index outside 16-bit range");
|
||||
}
|
||||
if (value > upperBound)
|
||||
upperBound = value;
|
||||
if (value < lowerBound)
|
||||
lowerBound = value;
|
||||
}
|
||||
} else {
|
||||
lowerBound = 0;
|
||||
upperBound = count - 1;
|
||||
|
@ -462,7 +462,7 @@ inline u32 ComputeMiniHashRange(const void *ptr, size_t sz) {
|
||||
u32 DrawEngineDX9::ComputeMiniHash() {
|
||||
u32 fullhash = 0;
|
||||
const int vertexSize = dec_->GetDecVtxFmt().stride;
|
||||
const int indexSize = (dec_->VertexType() & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT ? 2 : 1;
|
||||
const int indexSize = IndexSize(dec_->VertexType());
|
||||
|
||||
int step;
|
||||
if (numDrawCalls < 3) {
|
||||
@ -501,7 +501,7 @@ void DrawEngineDX9::MarkUnreliable(VertexArrayInfoDX9 *vai) {
|
||||
ReliableHashType DrawEngineDX9::ComputeHash() {
|
||||
ReliableHashType fullhash = 0;
|
||||
const int vertexSize = dec_->GetDecVtxFmt().stride;
|
||||
const int indexSize = (dec_->VertexType() & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT ? 2 : 1;
|
||||
const int indexSize = IndexSize(dec_->VertexType());
|
||||
|
||||
// TODO: Add some caps both for numDrawCalls and num verts to check?
|
||||
// It is really very expensive to check all the vertex data so often.
|
||||
|
@ -840,6 +840,8 @@ void GPU_DX9::Execute_Prim(u32 op, u32 diff) {
|
||||
int indexSize = 1;
|
||||
if ((vertexType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT)
|
||||
indexSize = 2;
|
||||
else if ((vertexType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_32BIT)
|
||||
indexSize = 4;
|
||||
gstate_c.indexAddr += count * indexSize;
|
||||
} else {
|
||||
gstate_c.vertexAddr += bytesRead;
|
||||
|
@ -471,7 +471,7 @@ inline u32 ComputeMiniHashRange(const void *ptr, size_t sz) {
|
||||
u32 DrawEngineGLES::ComputeMiniHash() {
|
||||
u32 fullhash = 0;
|
||||
const int vertexSize = dec_->GetDecVtxFmt().stride;
|
||||
const int indexSize = (dec_->VertexType() & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT ? 2 : 1;
|
||||
const int indexSize = IndexSize(dec_->VertexType());
|
||||
|
||||
int step;
|
||||
if (numDrawCalls < 3) {
|
||||
@ -510,7 +510,7 @@ void DrawEngineGLES::MarkUnreliable(VertexArrayInfo *vai) {
|
||||
ReliableHashType DrawEngineGLES::ComputeHash() {
|
||||
ReliableHashType fullhash = 0;
|
||||
const int vertexSize = dec_->GetDecVtxFmt().stride;
|
||||
const int indexSize = (dec_->VertexType() & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT ? 2 : 1;
|
||||
const int indexSize = IndexSize(dec_->VertexType());
|
||||
|
||||
// TODO: Add some caps both for numDrawCalls and num verts to check?
|
||||
// It is really very expensive to check all the vertex data so often.
|
||||
|
@ -1009,6 +1009,8 @@ void GPU_GLES::Execute_Prim(u32 op, u32 diff) {
|
||||
int indexSize = 1;
|
||||
if ((gstate.vertType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT)
|
||||
indexSize = 2;
|
||||
else if ((gstate.vertType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_32BIT)
|
||||
indexSize = 4;
|
||||
gstate_c.indexAddr += count * indexSize;
|
||||
} else {
|
||||
gstate_c.vertexAddr += bytesRead;
|
||||
|
@ -48,6 +48,12 @@ void GeDescribeVertexType(u32 op, char *buffer, int len) {
|
||||
"u16",
|
||||
"float",
|
||||
};
|
||||
static const char *typeNamesI[] = {
|
||||
NULL,
|
||||
"u8",
|
||||
"u16",
|
||||
"u32",
|
||||
};
|
||||
static const char *typeNamesS[] = {
|
||||
NULL,
|
||||
"s8",
|
||||
@ -72,8 +78,8 @@ void GeDescribeVertexType(u32 op, char *buffer, int len) {
|
||||
w += snprintf(w, end - w, "unknown weights (%d), ", weightCount);
|
||||
if (morphCount > 0 && w < end)
|
||||
w += snprintf(w, end - w, "%d morphs, ", morphCount);
|
||||
if (typeNames[idx] && w < end)
|
||||
w += snprintf(w, end - w, "%s indexes, ", typeNames[idx]);
|
||||
if (typeNamesI[idx] && w < end)
|
||||
w += snprintf(w, end - w, "%s indexes, ", typeNamesI[idx]);
|
||||
|
||||
if (w < buffer + 2)
|
||||
snprintf(buffer, len, "none");
|
||||
|
@ -336,6 +336,8 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
|
||||
int indexSize = 1;
|
||||
if ((gstate.vertType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT)
|
||||
indexSize = 2;
|
||||
else if ((gstate.vertType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_32BIT)
|
||||
indexSize = 4;
|
||||
gstate_c.indexAddr += count * indexSize;
|
||||
} else {
|
||||
gstate_c.vertexAddr += bytesRead;
|
||||
|
@ -227,8 +227,10 @@ void TransformUnit::SubmitSpline(void* control_points, void* indices, int count_
|
||||
u16 index_lower_bound = 0;
|
||||
u16 index_upper_bound = count_u * count_v - 1;
|
||||
bool indices_16bit = (vertex_type & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT;
|
||||
u8* indices8 = (u8*)indices;
|
||||
u16* indices16 = (u16*)indices;
|
||||
bool indices_32bit = (vertex_type & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_32BIT;
|
||||
u8 *indices8 = (u8 *)indices;
|
||||
u16 *indices16 = (u16 *)indices;
|
||||
u32 *indices32 = (u32 *)indices;
|
||||
if (indices)
|
||||
GetIndexBounds(indices, count_u*count_v, vertex_type, &index_lower_bound, &index_upper_bound);
|
||||
vdecoder.DecodeVerts(buf, control_points, index_lower_bound, index_upper_bound);
|
||||
@ -253,10 +255,17 @@ void TransformUnit::SubmitSpline(void* control_points, void* indices, int count_
|
||||
|
||||
for (int point = 0; point < 16; ++point) {
|
||||
int idx = (patch_u + point%4) + (patch_v + point/4) * count_u;
|
||||
if (indices)
|
||||
vreader.Goto(indices_16bit ? indices16[idx] : indices8[idx]);
|
||||
else
|
||||
if (indices) {
|
||||
if (indices_32bit) {
|
||||
vreader.Goto(indices32[idx]);
|
||||
} else if (indices_16bit) {
|
||||
vreader.Goto(indices16[idx]);
|
||||
} else {
|
||||
vreader.Goto(indices8[idx]);
|
||||
}
|
||||
} else {
|
||||
vreader.Goto(idx);
|
||||
}
|
||||
|
||||
patch.points[point] = ReadVertex(vreader);
|
||||
}
|
||||
@ -318,8 +327,10 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, u32 prim_type
|
||||
u16 index_lower_bound = 0;
|
||||
u16 index_upper_bound = vertex_count - 1;
|
||||
bool indices_16bit = (vertex_type & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT;
|
||||
u8* indices8 = (u8*)indices;
|
||||
u16* indices16 = (u16*)indices;
|
||||
bool indices_32bit = (vertex_type & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_32BIT;
|
||||
u8 *indices8 = (u8 *)indices;
|
||||
u16 *indices16 = (u16 *)indices;
|
||||
u32 *indices32 = (u32 *)indices;
|
||||
if (indices)
|
||||
GetIndexBounds(indices, vertex_count, vertex_type, &index_lower_bound, &index_upper_bound);
|
||||
vdecoder.DecodeVerts(buf, vertices, index_lower_bound, index_upper_bound);
|
||||
@ -349,10 +360,17 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, u32 prim_type
|
||||
{
|
||||
for (int vtx = 0; vtx < vertex_count; vtx += vtcs_per_prim) {
|
||||
for (int i = 0; i < vtcs_per_prim; ++i) {
|
||||
if (indices)
|
||||
vreader.Goto(indices_16bit ? indices16[vtx+i] : indices8[vtx+i]);
|
||||
else
|
||||
if (indices) {
|
||||
if (indices_32bit) {
|
||||
vreader.Goto(indices32[vtx + i]);
|
||||
} else if (indices_16bit) {
|
||||
vreader.Goto(indices16[vtx + i]);
|
||||
} else {
|
||||
vreader.Goto(indices8[vtx + i]);
|
||||
}
|
||||
} else {
|
||||
vreader.Goto(vtx+i);
|
||||
}
|
||||
|
||||
data[i] = ReadVertex(vreader);
|
||||
if (outside_range_flag)
|
||||
@ -528,12 +546,15 @@ bool TransformUnit::GetCurrentSimpleVertices(int count, std::vector<GPUDebugVert
|
||||
}
|
||||
break;
|
||||
case GE_VTYPE_IDX_32BIT:
|
||||
WARN_LOG_REPORT_ONCE(simpleIndexes32, G3D, "SimpleVertices: Decoding 32-bit indexes");
|
||||
for (int i = 0; i < count; ++i) {
|
||||
indices[i] = inds32[i];
|
||||
// These aren't documented and should be rare. Let's bounds check each one.
|
||||
if (inds32[i] != (u16)inds32[i]) {
|
||||
ERROR_LOG_REPORT_ONCE(simpleIndexes32Bounds, G3D, "SimpleVertices: Index outside 16-bit range");
|
||||
}
|
||||
indices[i] = (u16)inds32[i];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
indices.clear();
|
||||
|
@ -884,6 +884,8 @@ void GPU_Vulkan::Execute_Prim(u32 op, u32 diff) {
|
||||
int indexSize = 1;
|
||||
if ((gstate.vertType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT)
|
||||
indexSize = 2;
|
||||
else if ((gstate.vertType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_32BIT)
|
||||
indexSize = 4;
|
||||
gstate_c.indexAddr += count * indexSize;
|
||||
} else {
|
||||
gstate_c.vertexAddr += bytesRead;
|
||||
|
Loading…
Reference in New Issue
Block a user