# DirectX 11 Jerky rendering

This topic is 2450 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi folks,
I'm still in the process of debugging this problem but I've got no idea what the problem really is. Basically I have a simple direct x 11 simulation running - 3 balls that spin.

Basically it mostly runs incredibly fast as you'd expect - how ever every 1 or seconds it seems to stick or jump. Varying from quite small to very large jumps.

I'm not aware of any extra work that I'm doing in between these frames - generally after initialisation the workload is constant.

I just wanted to try brainstorm a few potential causes for my problems.

The only thing I thought it might be is that I'm writing a parallel game engine that uses a deferred shader and deferred DirectX contexts.
My engine is broken up into tasks using the Intel Threaded building blocks API. I have an input, asset, update and graphics task. The update task relies on both input and assets tasks and the graphics task relies on update the update task.

I've profiled in sampling and instrumentation mode and can't seem to find a trouble spot if its some mystery blocking function or something but nothing stands out.

DXUT seems to think I'm running at a consistent 500 frames per second - but I added a few getTickCounts() and I can see a few spikes appearing in the frame time.

Any help or ideas with this would be fantastic!!

##### Share on other sites
Sounds like a timer problem - you mentioned that you're using GetTickCount for profiling, so I'm curious if you're using it for your main timer too. If so you need to be aware that it's quite unsuitable for this job; you need a higher resolution timer (like QueryPerformanceCounter) instead.

##### Share on other sites
I'd like to see how you are calculating the spin angle. It could be error caused by concatenation of rotations.

##### Share on other sites
Hi folks, thanks for the responses!!

@mhagain
I'm not aware of any timers that I'm using. I'm running it as fast as it can go and my animation is a constant step per frame - so the higher the frame rate, the faster the animation. Might be DXUT trying to impose a timer of some sort??

@Hornsj3
My animation is based on a "centred camera" sort of like you'd find a 3d modelling package. It specifies vertical (from the positive y axis) and horizontal (from the positive x axis) rotation along with a radius (the camera's distance from the origin).
Also my cameras are implemented as a wrapper around a basic camera to give it some specialised functionality.
For completeness I've include the animation code and the basic and centred camera class implementations.

The 'updateCameraVectors()' in the centred camera class is where I do the rotational calculations and the set rotation functions clip the angle to be between 0 and 360 degrees for the horizontal rotation and 0 and 180 degrees for the vertical rotation.

Here's the animation code:
 ICameraManager* cameras = taskData->m_pRenderingService->getCameraManager(); ICentredCamera* camera = cameras->getCentredCamera(); // horizontal rotation animation camera->setHorizontalRotation(camera->getHorizontalRotation() + 0.01); // camera zoom animation if(camera->getRadius() >= 30.0f) { camera->setRadius(10.0f); } else { camera->setRadius(camera->getRadius() + 0.01f); } 

And here is the centred camera class:
 #include "CentredCameraWrapper.h" namespace GEngine_Graphics { CentredCameraWrapper::CentredCameraWrapper(Camera* cameraToWrap) { GEngineNonZeroAssert(cameraToWrap, L"No camera passed to CentredCameraWrapper constructor", L"No Camera"); m_pWrappedCamera = cameraToWrap; m_horizontalRotation = 0.0f; m_verticalRotation = D3DX_PI / 2.0f; m_radius = 1.0f; } CentredCameraWrapper::~CentredCameraWrapper() { } void CentredCameraWrapper::setMatrices() { m_pWrappedCamera->setMatrices(); } D3DXVECTOR3* CentredCameraWrapper::getCameraPosition() { return m_pWrappedCamera->getCameraPosition(); } D3DXMATRIXA16* CentredCameraWrapper::getViewMatrix() { return m_pWrappedCamera->getViewMatrix(); } D3DXMATRIXA16* CentredCameraWrapper::getProjectionMatrix() { return m_pWrappedCamera->getProjectionMatrix(); } void CentredCameraWrapper::setAsActive() { VectorUtilities::setVector(m_pWrappedCamera->getCameraTarget(), 0.0f, 0.0f, 0.0f); VectorUtilities::setVector(m_pWrappedCamera->getCameraUp(), 0.0f, 1.0f, 0.0f); updateCameraVectors(); } /* sets the horizontal rotation of the camera Parameter list rotation: to horizontal rotation of the camera */ void CentredCameraWrapper::setHorizontalRotation(float rotation) { m_horizontalRotation = fmod(rotation, 2.0f * (float)D3DX_PI); updateCameraVectors(); } /* sets the vertical rotation of the camera Parameter list rotation: to vertical rotation of the camera */ void CentredCameraWrapper::setVerticalRotation(float rotation) { m_verticalRotation = rotation; if (m_verticalRotation > D3DX_PI) { m_verticalRotation = D3DX_PI; } else if (m_verticalRotation < 0.0f) { m_verticalRotation = 0.0f; } updateCameraVectors(); } void CentredCameraWrapper::setRadius(float radius) { m_radius = radius; // do not let the radius equal 0!!! If the camera position is the same as it's lookat position the view matrix will break!! if (m_radius <= 1.0f) { m_radius = 1.0f; } updateCameraVectors(); } float CentredCameraWrapper::getHorizontalRotation() { return m_horizontalRotation; } float CentredCameraWrapper::getVerticalRotation() { return m_verticalRotation; } float CentredCameraWrapper::getRadius() { return m_radius; } /* recalculates and updates the camera vectors */ void CentredCameraWrapper::updateCameraVectors() { D3DXVECTOR3 forward(sinf(m_horizontalRotation), cosf(m_verticalRotation), cosf(m_horizontalRotation)); D3DXVec3Normalize(&forward, &forward); VectorUtilities::setVector( m_pWrappedCamera->getCameraPosition(), m_radius * forward.x, m_radius * forward.y, m_radius * forward.z); } } 

Finally here's the basic camera that the centred camera wraps up:
 // LCCREDIT start of 3DGraph1 #include "Camera.h" /*----------------------------------------------------------------------------\ * Initialisation and Clean up | *----------------------------------------------------------------------------*/ #define DEFAULT_CAMERA_FOV D3DX_PI / 4.0f #define DEFAULT_CAMERA_NEAR_PLANE 1.0f #define DEFAULT_CAMERA_FAR_PLANE 1000.0f #define SCREEN_WIDTH 800 #define SCREEN_HEIGHT 600 namespace GEngine_Graphics { /* Constructs and initialises a camera object */ Camera::Camera() { m_cameraPosition = D3DXVECTOR3( 0.0f, 0.0f, -1.0f ); m_cameraTarget = D3DXVECTOR3( 0.0f, 0.0f, 0.0f ); m_cameraUp = D3DXVECTOR3( 0.0f, 1.0f, 0.0f ); m_nearPlane = DEFAULT_CAMERA_NEAR_PLANE; m_farPlane = DEFAULT_CAMERA_FAR_PLANE; m_fieldOfView = DEFAULT_CAMERA_FOV; m_aspectRatio = (float)SCREEN_WIDTH / (float)SCREEN_HEIGHT; setMatrices(); } /* Destructs a camera object */ Camera::~Camera() { } /*----------------------------------------------------------------------------\ * Transformation pipeline code | *----------------------------------------------------------------------------*/ /* Sets the view and projection transformation matrices. */ void Camera::setMatrices() { setViewMatrix(); setProjectionMatrix(); } /* Sets the view transformation matrix. */ void Camera::setViewMatrix() { D3DXMatrixLookAtLH( &m_viewMatrix, &m_cameraPosition, &m_cameraTarget, &m_cameraUp ); } /* Sets the projection transformation matrix. */ void Camera::setProjectionMatrix() { D3DXMatrixPerspectiveFovLH( &m_projectionMatrix, m_fieldOfView, m_aspectRatio, m_nearPlane, m_farPlane ); } D3DXMATRIXA16* Camera::getViewMatrix() { return &m_viewMatrix; } D3DXMATRIXA16* Camera::getProjectionMatrix() { return &m_projectionMatrix; } D3DXVECTOR3* Camera::getCameraPosition() { return &m_cameraPosition; } D3DXVECTOR3* Camera::getCameraTarget() { return &m_cameraTarget; } D3DXVECTOR3* Camera::getCameraUp() { return &m_cameraUp; } float Camera::getNearClipPlane() { return m_nearPlane; } float Camera::getFarClipPlane() { return m_farPlane; } float Camera::getFieldOfView() { return m_fieldOfView; } void Camera::setNearClipPlane(float value) { m_nearPlane = value; } void Camera::setFarClipPlane(float value) { m_farPlane = value; } void Camera::setFieldOfView(float value) { m_fieldOfView = value; } } // end of 3DGraph1 

Any tips???

Thanks very much!

 I'll give the higher resolution timer a try and see what happens if I time the different sections of code. It's a performance thing - I'll expect to find group of functions that oddly take ages every now and again. Hopefully the timer can show this.

##### Share on other sites
At 500hz, your frame time is just 2ms, so small jitter values will have a large impact. Windows thread scheduling granularity defaults to 15ms.
If you've got other programs running, it could be that your thread called Sleep, and another program got the CPU for 15ms, resulting in one frame that's 7 times longer than the surrounding ones.
Do you have a virus scanner running?

Also, at 500hz, assuming you've got a regular 60hz monitor, then your monitor is only displaying every 8(and a 3rd)th frame. If your rotation speed is fixed per frame, this means that you'll have three frames where you see "[font=courier new,courier,monospace]rotation*8[/font]" movement, but the fourth frame you'll see "[font=courier new,courier,monospace]rotation*9[/font]" movement.

If there's some jitter in your frame time (which you should expect a small amount of), and for some reason your frame times are between 1.5 and 2.5ms, instead of a solid 2ms, then:
1.5ms == 666hz == every 11.1th frame displayed == movement per refresh: 11,11,11,11,11,11,11,11,11,12,...
2ms == 500hz == every 8.3th frame displayed == movement per refresh: 8,8,8,9,8,8,8,9,8...
2.5ms == 400hz == every 6.6th frame displayed == movement per refresh: 6,7,6,8,7...

So with such low frame-times, frame-rates higher than the display rate, and with non frame-rate independent movement, you should expect some jitter.
If you vsync'ed to 60, you probably wouldn't be noticing these issues right now

I would start by implementing frame-rate independent movement - where your rotations take into account the actual time passed.

##### Share on other sites
Hi Hodgman!
Thanks for the advice. I think I ended up discounting VSync because I thought it was pausing elsewhere in the application but I've just switched it on and its definitely alleviating the problem.
If full screen mode I can now only see a jerk every few seconds rather than quite constantly - but its still quite bad in windowed mode!

Although I know of VSync I've never had any problems that have meant I had to worry about it. The pre-cursor to this engine was a sample framework I put together with no VSync and all the animations where constant step. It ran at a few hundred fps and never had any trouble with stuttering animations.....

I've read a bit about vsyc and I think I understand what it's all about - but I don't understand why it's suddenly a problem for me when other projects have been fine with no vsync and didn't display any sort of visible stammer problems. I've had them all running fine on this machine with an identical set-up.

Yeah, there is an anti-virus app running in the background and could possibly be causing me a problem...but I can't switch it off - its all in German
I don't think I should need to worry about windows thread scheduling stuff too much. Threaded building blocks works with a thread pool idea. It sets up a thread for each available hardware thread and just keeps pushing tasks into them.

##### Share on other sites
Ok I think I've tracked down more of my problem - I had quite a lot of debug messages printing. As soon as I removed them the stammering reduced further. So I've compiled it under release mode and now its barely noticeable.
I'm still unsure as to why it suddenly became an issue for me though considering in my past experience its not been much of a problem....

1. 1
2. 2
Rutin
19
3. 3
khawk
18
4. 4
5. 5

• 9
• 12
• 16
• 26
• 10
• ### Forum Statistics

• Total Topics
633769
• Total Posts
3013756
×