Unexplained framerate drop

Heya guys!

I have this function:
1
2
3
4
5
6
7
8
9
10
11
mgBool Visible;
Visible = CCameraManager::Instance()->GetCurrent()->IsSphereVisible(m_BoundingSphere);
Visible = TRUE;
if (Visible)
{
	MeshVector::const_iterator It;
	for ( It = m_Meshes.begin(); It != m_Meshes.end(); ++It )
	{
		(*It)->Render();
	}	
}


This is how my Model::Render looks, i'm currently rendering 250models at 70fps with that code but if i remove the line: Visible = TRUE, i go down to around 8fps when looking at all my models(should be same thing as when i had Visible = TRUE) tho some times, if i look away from all the models and then back i can get 70fps, then i look away and back at them again it can go down to 8fps again if I'm unlucky, seems completely random.

Things I've tried that didn't change anything:

Moved the IsSphereVisible to update and saved it in a member variable

Ran IsSphereVisible 10times per model to make sure that function didn't have some weird impact but i stayed at around 70fps as long as i had Visible = TRUE.

It's not a cache problem since i can do loads of calucations in before rendering each model as long as i set Visible = TRUE before the if-check.

Made the Visible volatile to make sure it wasn't a target of any optimizations, didn't do any difference

Tried in Release config as well, going from 250 to 10fps there.

Tried exchanging my IsSphereVisible to a randomize if it should be rendered or not, same problem

Tried rebuilding

Tried rebooting

I honestly have no clue what more i could even try, this doesn't feel like it should be happening and would like to see if any of you got any ideas.

[Edit]
More things I've tried:
Looking at the dissembly, nothing weird there.

Done some profiling and it doesn't even seem to be the Model::Render function that takes more time, it's the D3D::EndRender(all i do there is present on the swapchain).

The framerate drop will only happen if atleast one model as been culled(not sent to directx rendering pipeline) So if i start my program where all the models are visible in the camera it's fine i can look around without getting any issues, but as soon as my IsSphereVisible has returned false once, the framerate usually drops to the ground.
[/Edit]
Last edited on
That's strange and it looks like you've done all the standard tests. Did you compare the disassembly for when you have Visible = TRUE; and when you don't?
Can you actually feel the lag when you're running around 8fps~. You're not calculating the fps wrong? To be safe do you want to share your IsSphereVisible code? Is your singleton built correctly, you're not always building a camera based on something that's not to do with the camera's singleton itself.
Thanks for your answers guys, I just wake up and noticed another thing, the fps drop only happens when the debugger is attached, otherwise i always stay around 70fps.

@Schaktar, Sorry but I've never used the dissembly before(don't know much assembly either) but where can i look at it? it isn't at Debug->Windows as msdn states, i'm running VS2010 Ultimate.

@Mythios Yea i can feel the lag, the singleton is build correctly, i can get the camera and manipulate it 100times per model without experiencing the low fps i get when i don't have Visible = TRUE; after. But yeah i can show the IsSphereVisible code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
static CVector3 Projection;
Projection.Copy(Sphere.GetPosition());
Projection.Subtract(m_Transform.GetWorldMatrix().GetPos());
static float f;
f = Projection.DotProduct(m_Transform.GetWorldMatrix().GetAt());
static float Radius;
Radius = Sphere.GetRadius();
if (f < m_NearClip-Radius || m_FarClip+Radius < f) return false;

static float r;
r = Projection.DotProduct(m_Transform.GetWorldMatrix().GetRight()); 
static float rLimit;
rLimit = m_RFactor * f;
static float rTop;
rTop = rLimit + Radius;
if (r < -rTop || rTop< r) return false;

static float u;
u = Projection.DotProduct(m_Transform.GetWorldMatrix().GetUp()); 
static float uLimit;
uLimit = m_UFactor * f;
static float uTop;
uTop = uLimit + Radius;
if (u < -uTop || uTop < u) return false;

return true;
Found something really interesting while profiling. This is how it looks when I have Visible = TRUE and 70fps:
[Profiler] BeginRender: 2.4996988314660883e-005
[Profiler] Models::Render: 0.009802132273220094
[Profiler] Text|Sprite ::Render: 0.00011926273942898446
[Profiler] EndRender: 0.00036953379110950491
[Profiler] CApplication::Render(): 0.010630044572943019

This is how it looks when i remove Visible = TRUE:
[Profiler] BeginRender: 2.3491145645102999e-005
[Profiler] Models::Render: 0.0091754005541501028
[Profiler] Text|Sprite ::Render: 0.00011715455969160342
[Profiler] EndRender: 0.11523732080472232
[Profiler] CApplication::Render(): 0.12490242139501265

The Visible = TRUE change is made in Models::Render, tho that doesn't have any impact on how long time it spends in Models::Render, it's EndRender that takes the insane amount of time, which is even more mindblowing for me tbh.

All EndRender does:
1
2
3
4
5
6
7
void CD3D::EndRender()
{
	//
	// Present our back buffer to our front buffer
	//
    m_pSwapChain->Present( 0, 0 );
}


And this is how i create my swapchain:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
DXGI_SWAP_CHAIN_DESC swapdesc;
	ZeroMemory( &swapdesc, sizeof( swapdesc ) );
	swapdesc.BufferCount							= 1;
	swapdesc.BufferDesc.Width						= width;
	swapdesc.BufferDesc.Height						= height;
	swapdesc.BufferDesc.Format						= DXGI_FORMAT_R8G8B8A8_UNORM;
	swapdesc.BufferDesc.RefreshRate.Numerator		= 60;
	swapdesc.BufferDesc.RefreshRate.Denominator		= 1;
	swapdesc.BufferUsage							= DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swapdesc.OutputWindow							= WindowHandle;
	swapdesc.SampleDesc.Count						= 4; // multisampling
	swapdesc.SampleDesc.Quality						= 0;
	swapdesc.Windowed								= TRUE;
	swapdesc.Flags									= DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;  // allow switching between fullscreen

	for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
	{
		m_driverType = driverTypes[driverTypeIndex];
		hr = D3D11CreateDeviceAndSwapChain( NULL, m_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels,
			D3D11_SDK_VERSION, &swapdesc, &m_pSwapChain, &m_pDevice, &m_featureLevel, &m_pDeviceContext );
		if( SUCCEEDED( hr ) )
			break;
	}
	if( FAILED( hr ) )
		return FALSE;
Last edited on
Nsanden wrote:

Sorry but I've never used the dissembly before(don't know much assembly either) but where can i look at it? it isn't at Debug->Windows as msdn states, i'm running VS2010 Ultimate.

I don't know either, but i know where to see it. Run your app from IDE (put breakpoint somewhere to stop it at that location), right click on the line that you wish and select "Go To Disassembly" and it will open its tab.

EDIT: I would advise you to only profile in Release build, as in debug you'll get odd results.
Last edited on
Heya sava!

Ah ye i could find the dissembly that way, thx. Going to look into it.

I profiled in release now and it sais the same thing:
[Profiler] BeginRender: 5.1198650764968075e-006
[Profiler] Models::Render: 0.00031833514034453682
[Profiler] Text|Sprite ::Render: 1.7166606432959884e-005
[Profiler] EndRender: 0.17527496687146127
[Profiler] CApplication::Render(): 0.17568726659438622

It seems its my swapchain::present that takes loads of time but it just doesn't make sence that it would do that because of a if-case in Models::Render :/
Last edited on
Took the dissembly for the whole render function and compared them in winmerge, the only difference is that when i got Visible = TRUE; the line 0010DA9E mov byte ptr [ebp-1Dh],1 is added so that seems to be correct.
Another lead, the framerate drop will only happen if atleast one model has been culled(not sent to directx rendering pipeline) So if i start my program where all the models are visible in the camera it's fine i can look around without getting any issues, but as soon as my IsSphereVisible has returned false once, the framerate usually drops to the ground.
This also happens if i add a model under runtime instead of culling an object, so the swapchain goes crazy as soon as the number of models being rendered changes during runtime.

Also this doesn't happen when i have fraps running, thought i'd capture it so you'd see how it behaves but nope.
Problem solved, I should've thought of this sooner, FML.

Works fine now when i upgraded my drivers to ones that came out 11 days ago(i've upgraded them just 1-2 months ago last time). Works fine now, fpsdrops has disapeared in other games as well.

Thanks those of you trying to help.
What Graphics Card are you using out of curiosity?
Nvidia Geforce 460 GTX^^
Topic archived. No new replies allowed.