Use std::vector for g_InlineVertexBuffer_Table instead of realloc

This commit is contained in:
ergo720 2020-10-10 17:20:54 +02:00
parent 8588230ee1
commit 47ea099a92
3 changed files with 82 additions and 17 deletions

View File

@ -4606,20 +4606,30 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetVertexData4f)
// Grow g_InlineVertexBuffer_Table to contain at least current, and a potentially next vertex
if (g_InlineVertexBuffer_TableLength <= g_InlineVertexBuffer_TableOffset + 1) {
UINT InlineVertexBuffer_TableLength_Original = g_InlineVertexBuffer_TableLength;
if (g_InlineVertexBuffer_TableLength == 0) {
g_InlineVertexBuffer_TableLength = PAGE_SIZE / sizeof(struct _D3DIVB);
} else {
g_InlineVertexBuffer_TableLength *= 2;
}
g_InlineVertexBuffer_Table = (struct _D3DIVB*)realloc(g_InlineVertexBuffer_Table, sizeof(struct _D3DIVB) * g_InlineVertexBuffer_TableLength);
EmuLog(LOG_LEVEL::DEBUG, "Reallocated g_InlineVertexBuffer_Table to %d entries", g_InlineVertexBuffer_TableLength);
for (unsigned i = 0; i < (g_InlineVertexBuffer_TableLength - InlineVertexBuffer_TableLength_Original); ++i) {
g_InlineVertexBuffer_Table.emplace_back(_D3DIVB{});
}
EmuLog(LOG_LEVEL::DEBUG, "Expanded g_InlineVertexBuffer_Table to %u entries", g_InlineVertexBuffer_TableLength);
// Sanity check: ensure that g_InlineVertexBuffer_Table is not growing indefinetly. This can happen if D3DDevice_Begin and D3DDevice_End
// are not patched, since they both reset g_InlineVertexBuffer_TableOffset back to zero, thus preventing further growth
if (g_InlineVertexBuffer_TableLength > 50000) {
LOG_TEST_CASE("g_InlineVertexBuffer_TableLength > 50000! This probably means that g_InlineVertexBuffer_Table is growing indefinitely.");
}
}
// Is this the initial call after D3DDevice_Begin() ?
if (g_InlineVertexBuffer_FVF == 0) {
// Set first vertex to zero (preventing leaks from prior Begin/End calls)
memset(&g_InlineVertexBuffer_Table[0], 0, sizeof(g_InlineVertexBuffer_Table[0]));
g_InlineVertexBuffer_Table[0] = {};
// Handle persistent vertex attribute flags, by resetting non-persistent colors
// to their default value (and leaving the persistent colors alone - see the
@ -4692,7 +4702,7 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetVertexData4f)
// Start a new vertex
g_InlineVertexBuffer_TableOffset++;
// Copy all attributes of the previous vertex (if any) to the new vertex
memcpy(&g_InlineVertexBuffer_Table[g_InlineVertexBuffer_TableOffset], &g_InlineVertexBuffer_Table[o], sizeof(g_InlineVertexBuffer_Table[o]));
g_InlineVertexBuffer_Table[g_InlineVertexBuffer_TableOffset] = g_InlineVertexBuffer_Table[o];
break;
}

View File

@ -47,7 +47,7 @@
// Inline vertex buffer emulation
extern xbox::X_D3DPRIMITIVETYPE g_InlineVertexBuffer_PrimitiveType = xbox::X_D3DPT_INVALID;
extern DWORD g_InlineVertexBuffer_FVF = 0;
extern struct _D3DIVB *g_InlineVertexBuffer_Table = nullptr;
std::vector<_D3DIVB> g_InlineVertexBuffer_Table;
extern UINT g_InlineVertexBuffer_TableLength = 0;
extern UINT g_InlineVertexBuffer_TableOffset = 0;
@ -69,6 +69,58 @@ uint32_t GetPixelContainerWidth(xbox::X_D3DPixelContainer* pPixelContainer);
uint32_t GetPixelContainerHeight(xbox::X_D3DPixelContainer* pPixelContainer);
void ApplyXboxMultiSampleOffsetAndScale(float& x, float& y);
_D3DIVB::_D3DIVB()
{
Position.x = 0.0f;
Position.y = 0.0f;
Position.z = 0.0f;
Rhw = 0.0f;
for (unsigned i = 0; i < 4; ++i) {
Blend[i] = 0.0f;
}
Normal.x = 0.0f;
Normal.y = 0.0f;
Normal.z = 0.0f;
Diffuse = 0u;
Specular = 0u;
Fog = 0.0f;
BackDiffuse = 0u;
BackSpecular = 0u;
for (unsigned i = 0; i < 4; ++i) {
TexCoord[i].x = 0.0f;
TexCoord[i].y = 0.0f;
TexCoord[i].z = 0.0f;
TexCoord[i].w = 0.0f;
}
}
struct _D3DIVB &_D3DIVB::operator=(const struct _D3DIVB &Val)
{
Position.x = Val.Position.x;
Position.y = Val.Position.y;
Position.z = Val.Position.z;
Rhw = Val.Rhw;
for (unsigned i = 0; i < 4; ++i) {
Blend[i] = Val.Blend[i];
}
Normal.x = Val.Normal.x;
Normal.y = Val.Normal.y;
Normal.z = Val.Normal.z;
Diffuse = Val.Diffuse;
Specular = Val.Specular;
Fog = Val.Fog;
BackDiffuse = Val.BackDiffuse;
BackSpecular = Val.BackSpecular;
for (unsigned i = 0; i < 4; ++i) {
TexCoord[i].x = Val.TexCoord[i].x;
TexCoord[i].y = Val.TexCoord[i].y;
TexCoord[i].z = Val.TexCoord[i].z;
TexCoord[i].w = Val.TexCoord[i].w;
}
return *this;
}
void CxbxPatchedStream::Activate(CxbxDrawContext *pDrawContext, UINT uiStream) const
{
//LOG_INIT // Allows use of DEBUG_D3DRESULT

View File

@ -103,25 +103,28 @@ class CxbxVertexBufferConverter
extern xbox::X_D3DPRIMITIVETYPE g_InlineVertexBuffer_PrimitiveType;
extern DWORD g_InlineVertexBuffer_FVF;
extern struct _D3DIVB
struct _D3DIVB
{
D3DXVECTOR3 Position; // X_D3DVSDE_POSITION (*) > D3DFVF_XYZ / D3DFVF_XYZRHW
FLOAT Rhw; // X_D3DVSDE_VERTEX (*) > D3DFVF_XYZ / D3DFVF_XYZRHW
FLOAT Blend[4]; // X_D3DVSDE_BLENDWEIGHT > D3DFVF_XYZB1 (and 3 more up to D3DFVF_XYZB4)
FLOAT Blend[4]; // X_D3DVSDE_BLENDWEIGHT > D3DFVF_XYZB1 (and 3 more up to D3DFVF_XYZB4)
D3DXVECTOR3 Normal; // X_D3DVSDE_NORMAL > D3DFVF_NORMAL
D3DCOLOR Diffuse; // X_D3DVSDE_DIFFUSE > D3DFVF_DIFFUSE
D3DCOLOR Specular; // X_D3DVSDE_SPECULAR > D3DFVF_SPECULAR
FLOAT Fog; // X_D3DVSDE_FOG > D3DFVF_FOG unavailable; TODO : How to handle?
D3DCOLOR BackDiffuse; // X_D3DVSDE_BACKDIFFUSE > D3DFVF_BACKDIFFUSE unavailable; TODO : How to handle?
D3DCOLOR BackSpecular; // X_D3DVSDE_BACKSPECULAR > D3DFVF_BACKSPECULAR unavailable; TODO : How to handle?
D3DCOLOR Diffuse; // X_D3DVSDE_DIFFUSE > D3DFVF_DIFFUSE
D3DCOLOR Specular; // X_D3DVSDE_SPECULAR > D3DFVF_SPECULAR
FLOAT Fog; // X_D3DVSDE_FOG > D3DFVF_FOG unavailable; TODO : How to handle?
D3DCOLOR BackDiffuse; // X_D3DVSDE_BACKDIFFUSE > D3DFVF_BACKDIFFUSE unavailable; TODO : How to handle?
D3DCOLOR BackSpecular; // X_D3DVSDE_BACKSPECULAR > D3DFVF_BACKSPECULAR unavailable; TODO : How to handle?
D3DXVECTOR4 TexCoord[4]; // X_D3DVSDE_TEXCOORD0 > D3DFVF_TEX1 (and 4 more up to D3DFVF_TEX4)
// (*) X_D3DVSDE_POSITION and X_D3DVSDE_VERTEX both set Position, but Rhw seems optional,
// hence, selection for D3DFVF_XYZ or D3DFVF_XYZRHW is rather fuzzy. We DO know that once
// D3DFVF_NORMAL is given, D3DFVF_XYZRHW is forbidden (see D3DDevice_SetVertexData4f)
}
*g_InlineVertexBuffer_Table;
// (*) X_D3DVSDE_POSITION and X_D3DVSDE_VERTEX both set Position, but Rhw seems optional,
// hence, selection for D3DFVF_XYZ or D3DFVF_XYZRHW is rather fuzzy. We DO know that once
// D3DFVF_NORMAL is given, D3DFVF_XYZRHW is forbidden (see D3DDevice_SetVertexData4f)
_D3DIVB();
struct _D3DIVB &operator=(const struct _D3DIVB &Val);
};
extern std::vector<_D3DIVB> g_InlineVertexBuffer_Table;
extern UINT g_InlineVertexBuffer_TableLength;
extern UINT g_InlineVertexBuffer_TableOffset;