You Can Now Play Mass Effect on AMD CPUs without Black Blobs as Characters

Tsing

The FPS Review
Staff member
Joined
May 6, 2019
Messages
11,302
Points
83
mass-effect-amd-cpu-black-blobs-1024x576.jpg
Image: Silent



Playing Mass Effect with an AMD CPU has been a pretty weird experience. For nearly a decade, running the PC port on an FX or Ryzen processor would result in a strange graphical glitch, whereby character models rendered as ugly, black blobs in Noveria and Ilos. What’s interesting (and sad) is that nobody at AMD, BioWare, Demiurge Studios, or EA attempted to address it, but thanks to the work of talented game developer and modder Adrian (AKA Silent or CookiePLMonster), we finally have a fix that doesn’t involve disabling game features or modifying maps!



Silent has posted a technical, long-winded post for those of you who are interested in the specifics, but if you want to jump right to the patch, you can grab it...

Continue reading...
 
Ayn Rand would be proud. This is a great achievement of the human spirit in a time were humans are struggling to keep the title of rational beings. And i got to learn what NaNs are.
 
Reading the technical explanation, I don't think they actually resolved why it was broken. This is just such an amateur call and I'm disgusted looking at it.
Code:
int __thiscall InvertMatrix(void *this, int a2)
{
  D3DXMatrixInverse(a2, 0, this);
  return a2;
}
Looking at the D3DXMatrixInverse() function reveals all kinds of wrong in which the developers invoked this function:
Code:
D3DXMATRIX* D3DXMatrixInverse(
  _Inout_       D3DXMATRIX *pOut,
  _Inout_       FLOAT      *pDeterminant,
  _In_    const D3DXMATRIX *pM
);
Giving pOut, the pointer that is supposed to contain the result, an int. Also giving pM, the pointer to the matrix that is supposed to be inversed, a void*. Not to mention the lack of error handling. If I'm reading this correctly (I have not done any programming going on 10 years, by the way), this function is always going to error out. I suspect that Intel's SSE implementation is able to handle the void* by returning an infinite matrix like Cramer's Rule is supposed to, while AMD does not do so.

The new XMMatrixInverse() function is noted to explicitly return an infinite matrix when the determinant is calculated as zero, which it will be if you pass it a one-dimensional matrix.

Code:
XMMATRIX XM_CALLCONV XMMatrixInverse(
  XMVECTOR  *pDeterminant,
  FXMMATRIX M
);
I'm going to assume they changed the game's InvertMatrix() function to this:
Code:
int __thiscall InvertMatrix(void *this, int a2)
{
  return XMMatrixInverse(this, a2);
}
 
Last edited:
Become a Patron!
Back
Top