Hi, I don't know if this is the right place to post this, but sorry if not, and I'd like to be pointed to the right one
I have been working last weeks on making the game Everquest to work under wine, since 0.9.49 it was working flawlesly, but most models
were not shown properly. This corresponds with bug http://bugs.winehq.org/show_bug.cgi?id=8357.
These are my findings:
The main executable is eqgame.exe it typically accesses D3D through a custom dll eqgraphicsdx9 which interacts with D3D itself or through
d3dx9_30.dll
Using channels and adding some extra messages into certain source files I got to track a possible reason:
The game was declaring vertex lists with a vertex of type '0xfe' and +189 offset
Sadly, I could not get any extra information tracking just from source code, so I had to run the game under Windows on a computer and
using windbg to debug it, while running the same time on another computer the game under Debian etch using winedbg to debug, and so
tracing both programs in assambler (I burnt my eyelashes there!), the fact that I could have d3d dll symbols availables on the windows box
was the key here, I really missed winedbg to be able to read pdb files :(
After many hours I was able to track down the reason, and to my surprise it seems its not wine's fault (for the most of it)
The 'troublesome' vertex are apparently Blended ones on a Mesh setup.
When d3dx9_30 calls ConvertToIndexedBlendedMesh, it calls GetDeviceInfo to get the device capabilites, in the end wine returns the
capabilites through IWineD3DImpl_GetDeviceCaps in wine/dlls/wined3d/directx.c
Here comes the fun thing, the attribute MaxVertexBlendMatrices in D3DCAPS9, from (MSDN):
"Maximum number of matrices that this device can apply when performing multimatrix vertex blending. For a given physical device, this
capability may vary across Direct3D devices depending on the parameters supplied to IDirect3D9::CreateDevice."
At the moment is set in wine as *pCaps->MaxVertexBlendMatrices = GL_LIMITS(blends) which results in a value of 0 (at least in my Linux
computer/build), while under Windows (XPSP2 DX9c) results in a value of 4
d3dx9_30 has a check right after capabilites are returned comparing that value with 2, resulting in different code paths for the remaining
of MaxVertexBlendMatrices function, when the value was 0 both Linux and Windows (hacking the returned value to be 0) make those odd '0xfe'
vertexes to be inserted (in Linux that makes the models to not be shown, in Windows it makes eqgame.exe to crash)
I proceeded then to try to 'hack' wine to return a value of 4, adding the line
pCaps->MaxVertexBlendMatrices=0x4;
Before returning from function IDirect3DDevice9Impl_GetDeviceCaps(LPDIRECT3DDEVICE9 iface, D3DCAPS9* pCaps) at wine/dlls/d3d9/directx.c
The result: MaxVertexBlendMatrices runs the same path as Windows does, the odd '0xfe' vertexes are not generated and the models work are
now shown as expected
My apologies for the long post, but I thought it would be handy to tell the full story to justify calling your atention on this
- d3dx9_30 ConvertToIndexedBlendedMesh shows an 'odd' behavior when MaxVertexBlendMatrices capabilites in D3DCAPS9 is 0 - Is wine reporting the right value for MaxVertexBlendMatrices ??? As it seems the game works flawlesly in wine when it's hacked to be 4
(I don't know if this 'hack' would affect other programs in any other way
Julio Fernandez wrote:
Hi, I don't know if this is the right place to post this, but sorry if not, and I'd like to be pointed to the right one
Please one message is enough! And please do not cross post! The bugzilla and/or wine-devel is enough.
What you failed to specify is your video card and driver version you are using.
Otherwise thanks for analysis this indeed should let someone who knows the area fix it or have a better explanation to what is going on.
Vitaliy
Am Samstag, 9. Februar 2008 16:00:51 schrieb Julio Fernandez:
At the moment is set in wine as *pCaps->MaxVertexBlendMatrices = GL_LIMITS(blends) which results in a value of 0 (at least in my Linux
computer/build), while under Windows (XPSP2 DX9c) results in a value of 4
What we return depends on the features of the OpenGL implementation. If GL_ARB_vertex_blend is not supported, we return 0, otherwise we return the limited reported to us by OpenGL, which is 4 on implementations that support it.
That said, GL_ARB_vertex_blend is not very common. Only MacOS supports it, and it is software emulated there. The Linux ATI driver used to support it until ATI switched to a different codebase. So this constant ends up beeing 0 almost everywhere. The extension was dropped in favor of vertex programs, since vertex programs appeared shortly after vertex blending and no gl app was using it at this time. On Windows drivers emulate vertex blending using vertex shaders.
I am not sure if 0 is the correct value to return in case of no vertex blending support. What happens if you set it to 1? 1 would be a reasonable default as well, because we're still able to transform vertices with one matrix(ie, unblened transformation). It could also be that this game silently expects vertex blending to be supported: For one part, all dx8+ cards support this feature on Windows, and on older cards Windows has software vertex processing which can perform blending in a slow, but working fashion.
I have a patch for software emulated vertex blending somewhere, but I dropped it because I didn't come across an app which uses this function. Maybe its time to revive it, and continue the work on a fixed function replacement shader.
First my deep apologize for the multiple/double post, I am not too used to post on news and I was not seeing my posts so I though they were getting 'lost' somewhere
As for system specs I run 2x Geforce 7900GS on SLI configuration with Nvidia 169.07 driver, x64 architecture, Debian etch, XOrg 7.1.1
Stefan Dösinger escribió:
I am not sure if 0 is the correct value to return in case of no vertex blending support. What happens if you set it to 1? 1 would be a reasonable default as well, because we're still able to transform vertices with one matrix(ie, unblened transformation). It could also be that this game silently expects vertex blending to be supported: For one part, all dx8+ cards support this feature on Windows, and on older cards Windows has software vertex processing which can perform blending in a slow, but working fashion.
1 won't work as d3dx9_30 does <2 (or <=2, I cant rememeber the exact asm comparison) check against the returned value so both 0 and 1 will work the same way
The game made a requirement to have DX9c many months ago
The odd part of it all is the own d3dx9_30 declaring type '0xfe' vertexes and odd offsets when receiving a 0 as value
On a side note, what's the status of 2.0 and 1.4 shaders in wine? wine reports
fixme:d3d:IWineD3DDeviceImpl_CreateVertexBuffer Out of memory!
trying to
D3DCREATERESOURCEOBJECTINSTANCE(object, VertexBuffer, WINED3DRTYPE_VERTEXBUFFER, Size)
when loading data from some zones, and then freezing the screen (although the rest of wine and the game keeps running in the background)