Need help with weird d3d9 BeginScene failed

Started by
1 comment, last by 21st Century Moose 12 years, 11 months ago
Hi, there. I'm a newbie, I have gotten D3DERR_INVALIDCALL sometimes and at some computers when render to surface. The Directx debug output show that BeginScene already in BeginScene/EndScene pair. I've done some research but got nothing. I know that I cannot call BeginScene in BeginScene/EndScene pair. But obviously I didn't.
My code looks like this:

while(running)
{
DoSomePrepare();
RenderToSurface(pASurface); // both RT surface are in D3DPOOL_SYSTEMMEM
DoOthrePrepare();
RenderToSurface(pAnotherSurface);
}

RenderToSurface(IDirect3DSurface9 *pSurface)
{
pRenderToASurface->BeginScene(pSurface, NULL); // BeginScene already in Begin/End pair
RenderScene();
pRenderToSurface->EndScene(D3DX_FILTER_NONE);
}
RenderScene()
{
// Use critical section lock resource
for_each(primitiveInScene)
{
DoCPUApplicationWork();
UpdateShaderParas();
BeginPass();
Render();
EndPass();
}
// Unlock critical section
}

Another question:
Which is more efficient:
1. Begin/End effect for each primitive, just like what I do.
2. Begin/End effect one/several time(s) and use CommitChanges.

Any reply will be appreciated.
Advertisement
I don't really see the cause of the invalid call for sure, however it would be interesting what exactly pRenderToASurface is, as the normal Direct3DDevice doesn't have any parameters in the BeginScene or EndScene-calls. This is pseudo-code, isn't it? It would be helpful to see your full code. Aside, how did you check for the invald calls? Using the debugger or with some debug-output with files or messageboxes? Did you use debug or release-mode? I experienced random invalid calls too, using the debugger in release mode.

Another question:
Which is more efficient:
1. Begin/End effect for each primitive, just like what I do.
2. Begin/End effect one/several time(s) and use CommitChanges.

Any reply will be appreciated. [/quote]

2. should be more efficient. What your 1. approach does is basically load and unload a vertex and pixelshader for every primitive. This is very expensive. Your main goal to get good performance is having as less shader switches as possible. Also, the effect framework restores the old renderstates from before the begin-call after every end-call, so this will be even more slow. To sum up: Sort your primitves for effects and draw them using as less begin/end as possible.
pRenderToASurface is obviously an instance of ID3DXRenderToSurface.

What the OP should do is run the program under PIX; that will confirm where the other BeginScene call is coming from - a lot of D3DX calls for example will make standard D3D calls behind your back, so you really need to watch what they're doing.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

This topic is closed to new replies.

Advertisement