Hi, When I was trying to find out how the native d3dx9_36.dll handles ID3DXRenderToSurface->BeginScene() with WINEDEBUG="+d3d9,heap" I had the problem that I had to find out what functions are called within the dll and what functions are called by the d3d9 functions (and thus are irrelevant for d3dx9). For example this is what I got for BeginScene: (fixmes were disabled)
trace:d3d9:IDirect3DSurface9Impl_GetDesc (0xc3b428) Relay trace:d3d9:IDirect3DDevice9Impl_CreateDepthStencilSurface Relay trace:d3d9:IDirect3DDevice9Impl_CreateSurface (0x1264c8) Relay trace:heap:RtlAllocateHeap (0x110000,0000000a,0000001c): returning 0xc3b450 trace:d3d9:IDirect3DDevice9Impl_CreateSurface (0x1264c8) : w(256) h(256) fmt(0) surf@(nil) trace:heap:RtlAllocateHeap (0x110000,0000000a,00000114): returning 0x1b81e0 trace:d3d9:IDirect3DDevice9Impl_AddRef (0x1264c8) : AddRef from 4 trace:d3d9:IDirect3DDevice9Impl_CreateSurface (0x1264c8) : Created surface 0xc3b450 trace:d3d9:IDirect3DDevice9Impl_BeginStateBlock (0x1264c8) Relay trace:heap:RtlAllocateHeap (0x110000,0000000a,0000c994): returning 0xd1df30 trace:heap:RtlAllocateHeap (0x110000,0000000a,000006a0): returning 0xc3b820 trace:heap:RtlAllocateHeap (0x110000,0000000a,000001a8): returning 0xa7b7e8 trace:heap:RtlAllocateHeap (0x110000,0000000a,000006b0): returning 0x1b8300 trace:heap:RtlAllocateHeap (0x110000,0000000a,000001ac): returning 0xd2a8d0 trace:heap:RtlAllocateHeap (0x110000,00000002,000001ac): returning 0xc3bec8 trace:heap:RtlAllocateHeap (0x110000,00000002,000001a8): returning 0xa7b998 trace:d3d9:IDirect3DDevice9Impl_SetViewport (0x1264c8)0xc3b384 Relay trace:d3d9:IDirect3DDevice9Impl_EndStateBlock (0x1264c8) Relay trace:heap:RtlAllocateHeap (0x110000,0000000a,00000010): returning 0xd1dec8 trace:d3d9:IDirect3DDevice9Impl_AddRef (0x1264c8) : AddRef from 5 trace:d3d9:IDirect3DDevice9Impl_EndStateBlock (0x1264c8)Returning 0xd1dec8 0xd1df30 trace:d3d9:IDirect3DStateBlock9Impl_Capture (0xd1dec8) Relay trace:d3d9:IDirect3DDevice9Impl_GetRenderTarget (0x1264c8) Relay trace:d3d9:IDirect3DSurface9Impl_AddRef (0x177d20) trace:d3d9:IDirect3DDevice9Impl_AddRef (0x1264c8) : AddRef from 6 trace:d3d9:IDirect3DSurface9Impl_AddRef (0x177d20) : AddRef from 0 trace:d3d9:IDirect3DDevice9Impl_GetDepthStencilSurface (0x1264c8) Relay trace:d3d9:IDirect3DSurface9Impl_AddRef (0x177d48) trace:d3d9:IDirect3DDevice9Impl_AddRef (0x1264c8) : AddRef from 7 trace:d3d9:IDirect3DSurface9Impl_AddRef (0x177d48) : AddRef from 0 trace:d3d9:IDirect3DDevice9Impl_SetRenderTarget (0x1264c8) Relay trace:heap:RtlFreeHeap (0x110000,00000002,0x178110): returning TRUE trace:d3d9:IDirect3DDevice9Impl_SetDepthStencilSurface (0x1264c8) Relay trace:d3d9:IDirect3DDevice9Impl_SetViewport (0x1264c8)0xc3b384 Relay trace:d3d9:IDirect3DDevice9Impl_BeginScene (0x1264c8) Relay trace:d3d9:IDirect3DSurface9Impl_AddRef (0xc3b428) trace:d3d9:IDirect3DSurface9Impl_AddRef (0xc3b428) : Forwarding to 0xa7b6e8 trace:d3d9:IDirect3DTexture9Impl_AddRef (0xa7b6e8) : AddRef from 2 trace:heap:RtlAllocateHeap (0x110000,00000002,0000001d): returning 0xc3b478
However, after distinguishing the direct and the indirect function calls, I would've found an output like this much better:
trace:d3d9:IDirect3DSurface9Impl_GetDesc (0xc3b428) Relay trace:d3d9:IDirect3DDevice9Impl_CreateDepthStencilSurface Relay trace:d3d9:IDirect3DDevice9Impl_CreateSurface (0x1264c8) Relay trace:heap:RtlAllocateHeap (0x110000,0000000a,0000001c): returning 0xc3b450 trace:d3d9:IDirect3DDevice9Impl_CreateSurface (0x1264c8) : w(256) h(256) fmt(0) surf@(nil) trace:heap:RtlAllocateHeap (0x110000,0000000a,00000114): returning 0x1b81e0 trace:d3d9:IDirect3DDevice9Impl_AddRef (0x1264c8) : AddRef from 4 trace:d3d9:IDirect3DDevice9Impl_CreateSurface (0x1264c8) : Created surface 0xc3b450 trace:d3d9:IDirect3DDevice9Impl_BeginStateBlock (0x1264c8) Relay trace:heap:RtlAllocateHeap (0x110000,0000000a,0000c994): returning 0xd1df30 trace:heap:RtlAllocateHeap (0x110000,0000000a,000006a0): returning 0xc3b820 trace:heap:RtlAllocateHeap (0x110000,0000000a,000001a8): returning 0xa7b7e8 trace:heap:RtlAllocateHeap (0x110000,0000000a,000006b0): returning 0x1b8300 trace:heap:RtlAllocateHeap (0x110000,0000000a,000001ac): returning 0xd2a8d0 trace:heap:RtlAllocateHeap (0x110000,00000002,000001ac): returning 0xc3bec8 trace:heap:RtlAllocateHeap (0x110000,00000002,000001a8): returning 0xa7b998 trace:d3d9:IDirect3DDevice9Impl_SetViewport (0x1264c8)0xc3b384 Relay trace:d3d9:IDirect3DDevice9Impl_EndStateBlock (0x1264c8) Relay trace:heap:RtlAllocateHeap (0x110000,0000000a,00000010): returning 0xd1dec8 trace:d3d9:IDirect3DDevice9Impl_AddRef (0x1264c8) : AddRef from 5 trace:d3d9:IDirect3DDevice9Impl_EndStateBlock (0x1264c8)Returning 0xd1dec8 0xd1df30 trace:d3d9:IDirect3DStateBlock9Impl_Capture (0xd1dec8) Relay trace:d3d9:IDirect3DDevice9Impl_GetRenderTarget (0x1264c8) Relay trace:d3d9:IDirect3DSurface9Impl_AddRef (0x177d20) trace:d3d9:IDirect3DDevice9Impl_AddRef (0x1264c8) : AddRef from 6 trace:d3d9:IDirect3DSurface9Impl_AddRef (0x177d20) : AddRef from 0 trace:d3d9:IDirect3DDevice9Impl_GetRenderTarget (0x1264c8) Finished trace:d3d9:IDirect3DDevice9Impl_GetDepthStencilSurface (0x1264c8) Relay trace:d3d9:IDirect3DSurface9Impl_AddRef (0x177d48) trace:d3d9:IDirect3DDevice9Impl_AddRef (0x1264c8) : AddRef from 7 trace:d3d9:IDirect3DSurface9Impl_AddRef (0x177d48) : AddRef from 0 trace:d3d9:IDirect3DDevice9Impl_SetRenderTarget (0x1264c8) Relay trace:heap:RtlFreeHeap (0x110000,00000002,0x178110): returning TRUE trace:d3d9:IDirect3DDevice9Impl_SetDepthStencilSurface (0x1264c8) Relay trace:d3d9:IDirect3DDevice9Impl_SetViewport (0x1264c8)0xc3b384 Relay trace:d3d9:IDirect3DDevice9Impl_BeginScene (0x1264c8) Relay trace:d3d9:IDirect3DSurface9Impl_AddRef (0xc3b428) trace:d3d9:IDirect3DSurface9Impl_AddRef (0xc3b428) : Forwarding to 0xa7b6e8 trace:d3d9:IDirect3DTexture9Impl_AddRef (0xa7b6e8) : AddRef from 2 trace:heap:RtlAllocateHeap (0x110000,00000002,0000001d): returning 0xc3b478
I have to admit that I have yet no real idea if this distinction is correct, but I hope it makes clear what I want to approach. All traces that have been made inside of a nested function call are written a bit more right, so that one can easily see that it hasn't been called directly by an application.
A suggestion for how to realize this system would be to 1) add a variable that counts how much right a debug output should be 2) modify the debug macros TRACE, FIXME, etc... in such a way that they recognize this variable 3) replace all TRACE("(%p): relayn", This) calls, which are usually at the beginning of a function, with a new macro, let's say NEWTRACE, which does exactly the same but also increments our tab (or space) counter by one. 4) make sure that there's also an ENDTRACE macro at the end of each function that decrements the counter again.
At least I would find this idea very useful, so feel free to leave a comment about either the thing itself or my implementation idea of it.
Best regards, Tony
PS: I know that there would be several workarounds that would help me in this case, but I'd like this proposal to get into the official tree if others like it, too.
PPS: We could also add a WINEDEBUG option that filters out any indirect function calls from e.g. the 4th level to make things more overviewable, however, it's just another idea, too ;-)
tony.wasserka@freenet.de wrote:
A suggestion for how to realize this system would be to
- add a variable that counts how much right a debug output should be
- modify the debug macros TRACE, FIXME, etc... in such a way that they recognize this variable
- replace all TRACE("(%p): relayn", This) calls, which are usually at the beginning of a function, with a new macro, let's say NEWTRACE, which does exactly the same but also increments our tab (or space) counter by one.
- make sure that there's also an ENDTRACE macro at the end of each function that decrements the counter again.
Have you looked at tools/examine-relay script? What you proposing will add unnecessary processing everywhere the debugging output is called. While it would only be useful for relay, which is already horribly slow just because it outputs so much.
Vitaliy.