Discussion:
IDirect3DDevice9::Reset fails with D3DERR_INVALIDCALL, even after freeing device objects
(too old to reply)
Mike Donovan
2004-03-06 13:45:26 UTC
Permalink
I started off developing a chess game using one of the simple D3D
sample apps as a skeleton. My game is considerably more complex than
the sample, and I use for example several of my own classes to
encapsulate game objects, each having their own vertex buffer and
rendering code. This may or may not be a good way of doing it, but it
has worked nicely up until this point. Nicely except for a problem I
have been avoiding, which is that the app crashed on window resize. I
have finally decided to bite the bullet and fix it.

After learning about the debug runtime and control panel switches, I
tracked the problem down to being a case of device objects (vertex
buffers) which I had created, not having been freed before the call to
Reset.

I added code to InvalidateDeviceObjects for all my vertex buffers, and
have verified that the VB pointers are indeed being set to zero when
invalidate is called. However, Reset call still fails with

The following D3DPOOL_DEFAULT surfaces/buffers/textures still exist
Direct3D9: (ERROR) : D3DRTYPE_VERTEXBUFFER
Direct3D9: (ERROR) : D3DRTYPE_VERTEXBUFFER
Direct3D9: (ERROR) : D3DRTYPE_VERTEXBUFFER
Direct3D9: (ERROR) : D3DRTYPE_VERTEXBUFFER
Direct3D9: (ERROR) : D3DRTYPE_VERTEXBUFFER
Direct3D9: (ERROR) : D3DRTYPE_VERTEXBUFFER
Direct3D9: (ERROR) : D3DRTYPE_VERTEXBUFFER
Direct3D9: (ERROR) : D3DRTYPE_VERTEXBUFFER
Direct3D9: (ERROR) :All user created D3DPOOL_DEFAULT surfaces must be
freed before Reset can succeed. Reset Fails.

I have included some code snippets in the hope that some kind soul can
point out the error of my ways. If not enough code I will post more.

Thanks in advance!!

Mike Donovan

------------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Name: InvalidateDeviceObjects()
// Desc: Invalidates device objects. Paired with
RestoreDeviceObjects()
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InvalidateDeviceObjects()
{
// TODO: Cleanup any objects created in RestoreDeviceObjects()
m_pFont->InvalidateDeviceObjects();
InvalidateMyDeviceObjects();
return S_OK;
}

HRESULT CMyD3DApplication::InvalidateMyDeviceObjects()
{
SAFE_RELEASE( g_IB );
SAFE_RELEASE( m_pVB );
m_pPieces->InvalidateDeviceObjects();
m_pSquareSelector->InvalidateDeviceObjects();
m_pChatWindow->InvalidateDeviceObjects();
return S_OK;
}
-------------------------------------------------------------------------------
HRESULT Pieces::InvalidateDeviceObjects()
{
m_pPawns->InvalidateDeviceObjects();
m_pKings->InvalidateDeviceObjects();
m_pQueens->InvalidateDeviceObjects();
m_pBishops->InvalidateDeviceObjects();
m_pKnights->InvalidateDeviceObjects();
m_pRooks->InvalidateDeviceObjects();
return S_OK;
}
-------------------------------------------------------------------------------
HRESULT Piece::InvalidateDeviceObjects()
{
SAFE_RELEASE( m_pPieceVB );
return S_OK;
}
-------------------------------------------------------------------------------
HRESULT SquareSelector::InvalidateDeviceObjects()
{
SAFE_RELEASE(m_pVB);
return S_OK;
}
-------------------------------------------------------------------------------
HRESULT ChatWindow::InvalidateDeviceObjects()
{
SAFE_RELEASE(m_pChatVB);
return S_OK;
}
-------------------------------------------------------------------------------

I pass a pointer to the D3DDevice to each of my classes, which stores
a local reference, and uses it to create the objects VB within the
class.

I figure the eight debug output stream error messages above correspond
to my eight VB's: 6 for the pieces + 1 for square + 1 for chat wnd.

I am wondering if the problem is something to do with the fact that my
user defined classes are instantiated in InitDeviceObjects, which
means the initial VBs are created then.

-------------------------------------------------------------------------------

HRESULT CMyD3DApplication::InitDeviceObjects()
{
----8<---BIG SNIP-----8<-------------
m_pPieces=new Pieces(m_pd3dDevice);
m_pPieces->CreateRenderList();
m_pSquareSelector=new SquareSelector(m_pd3dDevice);
m_pChatWindow=new ChatWindow(m_pd3dDevice, m_d3dsdBackBuffer.Width,
m_d3dsdBackBuffer.Height, m_pFont, m_pcUsername);
m_pChatWindow->SetVisibility(true);

return S_OK;
}


Once again, thanks in advance!

Mike
Mike Donovan
2004-03-07 07:24:56 UTC
Permalink
I am really hoping one of you MVPs might be able to point me in the
right direction. I have performed SAFE_RELEASE on all the Vertex
Buffers, but I still have the problem. I cant find any other
references to the VBs, so I am confused, and for the time being, at a
dead end.
Eyal Teler
2004-03-07 12:53:38 UTC
Permalink
Haven't read your source, but it does seem obvious that you're not
actually releasing all the buffers. One strategy to try for debugging
this would be to create just one of the pieces, which will make it
easier to see what's happening to the buffers. Another thing would be
to use debug prints to check what allocations and deallocations are
actually done. Note also that an object could potentially have more
than one reference, and 'release' just removes one reference. The
function 'Release' returns the reference count after the release. This
should be 0. (You say that the VB *pointers* are set to 0, but that
doesn't really matter, since they're being tracked by the references,
not the pointers.)

BTW, I'd suggest using buffers in the managed pool, instead of the
default pool. That way you won't have to reallocate them on reset.
However, don't use that as a solution to the current problem, since it
might alleviate it, but still leave you with unnecessary buffers or
lots of references.

Eyal
Post by Mike Donovan
I started off developing a chess game using one of the simple D3D
sample apps as a skeleton. My game is considerably more complex than
the sample, and I use for example several of my own classes to
encapsulate game objects, each having their own vertex buffer and
rendering code. This may or may not be a good way of doing it, but it
has worked nicely up until this point. Nicely except for a problem I
have been avoiding, which is that the app crashed on window resize. I
have finally decided to bite the bullet and fix it.
After learning about the debug runtime and control panel switches, I
tracked the problem down to being a case of device objects (vertex
buffers) which I had created, not having been freed before the call to
Reset.
I added code to InvalidateDeviceObjects for all my vertex buffers, and
have verified that the VB pointers are indeed being set to zero when
invalidate is called. However, Reset call still fails with
The following D3DPOOL_DEFAULT surfaces/buffers/textures still exist
Direct3D9: (ERROR) : D3DRTYPE_VERTEXBUFFER
Direct3D9: (ERROR) : D3DRTYPE_VERTEXBUFFER
Direct3D9: (ERROR) : D3DRTYPE_VERTEXBUFFER
Direct3D9: (ERROR) : D3DRTYPE_VERTEXBUFFER
Direct3D9: (ERROR) : D3DRTYPE_VERTEXBUFFER
Direct3D9: (ERROR) : D3DRTYPE_VERTEXBUFFER
Direct3D9: (ERROR) : D3DRTYPE_VERTEXBUFFER
Direct3D9: (ERROR) : D3DRTYPE_VERTEXBUFFER
Direct3D9: (ERROR) :All user created D3DPOOL_DEFAULT surfaces must be
freed before Reset can succeed. Reset Fails.
Loading...