Gee, invalid pipe ?!

Started by
5 comments, last by Supernat02 19 years, 7 months ago
Hi @ll, I'm facing half a problem. My app starts fine and renders everything I want it to but after exiting the app, an error message pops up "Invalid pipe state" ( Error code 230 ). Finally the debugger kicks in telling me the following: GetClientRect failed ? GetClientRect failed ? ( 2 times ) BitBlt failed ? The following line is causing the problem: g_lpD3DDevice->Present( NULL, NULL, Window->hWnd, NULL ); Does anyone have a clue ? Bye, Leoric
Advertisement
It sounds like your render loop is still executing after the window has been destroyed.
Yes, to fix that, add something like this. It will check the windows message queue for a WM_QUIT posting and skip presentation if it exists. For some reason, Windows destroys the window before you process the WM_QUIT message. Present calls GetClientRect to figure out where the "stuff" is going to be rendered and the window handle is no longer valid.

MSG msg;
PeekMessage(&msg, NULL, 0,0,PM_NOREMOVE);
if (msg.message != WM_QUIT)
pDevice->Present(NULL, NULL, NULL, NULL);

Chris
Chris ByersMicrosoft DirectX MVP - 2005
Hey,

thanks for replying. The problem I described earlier doesn't seem to be a problem of my code. The same error message pops up when I start other Direct3D apps ( not commercial games ) which I didn't code.

In my code, I already did testing for a valid window handle and the handle definitely is valid. As I said before, all my millions of polygons are rendered just fine. The error message occurs AFTER exiting the app.

By the way, the problem only occurs when building against the DX debug runtimes and - maybe that's the cause - since I changed from my old video card to a R9800 Pro. I uninstalled and reinstalled the video drivers correctly. It was a Radeon before as well.

I will try to figure out the WM_QUIT stuff. But the error is there even if I do Device->Present( NULL, NULL, NULL, NULL) instead of Device->Present( NULL, NULL, hWnd, NULL ).

Bye,
Leoric
Yes, it's a debug only problem. I believe the reason is that DirectX is aware that it can happen and so they don't cause it to throw a system exception. It's only thrown during debug to let you know that you are trying to render to an invalid window. The reason it still works when you don't pass hWnd in is because when you create the device, you pass it into the presentation parameters and that's the one it's using when it calls GetClientRect. It also just happens that if you breakpoint on the WM_QUIT message in your main message processing loop, you can also breakpoint on the code I provided (breakpoint when the WM_QUIT message is discovered in the message queue) and the one in the code I wrote will occur first, meaning that WM_QUIT has been posted between the message processing loop and the rendering loop, and something else occurs that causes the window to be invalid.

I don't know all the answers or causes, but trust me that this fixes the problem. I do intend on looking more into what goes on when you push the X button to close the window.

Chris
Chris ByersMicrosoft DirectX MVP - 2005
@Supernat02: I would really like to trust you but the method you provided didn't help. Still the freaky "Invalid Pipe State" occurs and the Debug Breakpoint is always at a certain adress.

I have set up a new post with pictures:
http://www.gamedev.net/community/forums/topic.asp?topic_id=270626

Please have a look.

Bye,
Leoric
Leoric,

The picture doesn't show GetClientRect failed and BitBlt failed. Did those go away? Those are the only two items that my code would fix. The picture did show a memory leak, where a DX object isn't being released. I'm sorry if my code doesn't fix your problem. It was the only thing that would fix mine. I even stripped out all of my other code and just called Begin, End, and Present. Are you using Visual C++ 6?

Anyway, the memory leak is a different thing. If that's the only problem you still have, it's not a big one. Did you release every object (including any surfaces (like for cursors), textures, meshes, and buffers you've used?) Perhaps you used a D3DXMaterialBuffer to load a mesh and forgot to release it when you were done. That's a common mistake because DirectX assigns the buffer when you pass in an address to an empty pointer to the Mesh creation or File Loading routine, and since you didn't create it with an actual CreateMaterialBuffer() call, it's easy to forget to release it. Not saying that is it, just trying to give you some ideas.
Chris ByersMicrosoft DirectX MVP - 2005

This topic is closed to new replies.

Advertisement