Sign in to follow this  

Flickering, but using double buffer

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello there,

I'm having a problem with extreme flickering.

In fact it's like I only draw every 50th frame something - the other frames are the background color.

I figured out, if I remove the clear call it doesn't flicker at all, but it's drawn with these "letfovers" from the previous frame.

It also doesn't flicker when I don't update the constant buffers.

I'm using the backbuffer.

I'm drawing in a wxWigets window in the idle event. (This shouldn't matter as wxWidgets uses native controls and windows...)

 

This is my render loop:

float color[] = {0.0f,0.25f,0.5f,1.0f};
_devcon->ClearRenderTargetView(_target, color);
_devcon->ClearDepthStencilView(_depthStencil, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f,0);
//Do rendering stuff here
//Set the primitive Topology
_devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
//Set index & vertex buffers
_devcon->IASetIndexBuffer(_indexBuffer, DXGI_FORMAT_R32_UINT, 0);
UINT stride = sizeof(Vertex), offset = 0;
_devcon->IASetVertexBuffers(0, 1, &_vertexBuffer, &stride, &offset);
//update the constant buffer
HRESULT hRes;
static float rotation = 0;
rotation += 0.001f;
D3D11_MAPPED_SUBRESOURCE mbuf;
hRes = _devcon->Map(_matrixBuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &mbuf);
if (FAILED(hRes))
	return false;
MatrixBuffer *matrices;
matrices = (MatrixBuffer*)(mbuf.pData);
matrices->world = XMMatrixRotationY(rotation) * XMMatrixRotationX(rotation / 2);
matrices->world = XMMatrixTranspose(matrices->world);
_devcon->Unmap(_matrixBuf, 0);
_devcon->VSSetConstantBuffers(0, 1, &_matrixBuf);
//Activate the shaders
_devcon->IASetInputLayout(_inputLayout);
_devcon->VSSetShader(_vertexShader, 0, 0);
_devcon->PSSetShader(_pixelShader, 0, 0);
_devcon->DrawIndexed(18, 0, 0);
_swapchain->Present(0,0);
return true;

Share this post


Link to post
Share on other sites

Afterall it wasn't driver's problem.

 

In your PyramidApp::Move() method you update your constant buffer, however you set only world matrix, while view and proj matrices are invalid.

Updating constant buffer with D3D11_MAP_WRITE_DISCARD flag means throwing away all old data, so you need to reset all values.

Reference driver worked 'correctly' because it doesn't throw away data.

I managed to get it working using following code:

	D3D11_MAPPED_SUBRESOURCE mbuf;																							 
	HR(_devcon->Map(_matrixBuf, 0, D3D11_MAP_WRITE_DISCARD, 0 , &mbuf));													 																								 
	MatrixBuffer *matrices;
	matrices = (MatrixBuffer*)(mbuf.pData);
	matrices->world = XMMatrixRotationY(rotation) * XMMatrixRotationX(rotation / 2);
	matrices->world = XMMatrixTranspose(matrices->world);
	matrices->view = XMMatrixTranspose(
		XMMatrixLookAtLH(
			XMVectorSet(0, 0, -5, 0),
			XMVectorSet(0, 0, 0, 0),
			XMVectorSet(0, 1, 0, 0)
		)
	);
	matrices->projection = XMMatrixTranspose(XMMatrixPerspectiveFovLH(XM_PIDIV4, 1.777f, 0.01f, 10000.0f));
	_devcon->Unmap(_matrixBuf, 0);

Share this post


Link to post
Share on other sites


Updating constant buffer with D3D11_MAP_WRITE_DISCARD flag means throwing away all old data, so you need to reset all values.

Good to know. Worked perfectly.

But I have 3 questions:

  • Why would the reference dirver work differntly on this flag?
  • Why does it render sometimes - there should be a need of a vaild view and projection matrix, but I didn't set anything.
  • Why does it work without the clear call?

Share this post


Link to post
Share on other sites

 

Why would the reference dirver work differntly on this flag?

Hardware driver allocates new buffer, where you write data, and later upload it to GPU. Reference driver doesn't need to do such sychronization, so you get to edit buffer directly, which still has previous values.

 

 

Why does it work without the clear call?

When you create buffer you set all values; right after creation everything is correct.

Your render loop in PyramidApp::Frame() method first draws and then updates, so first drawn frame is correct. Without clear call it never removes this.

 

 

Why does it render sometimes - there should be a need of a vaild view and projection matrix, but I didn't set anything.

Maybe matrices don't have constructors, meaning they'll be full of random values, which once in a while might be able to render something.

Other than that I have no idea, it shouldn't happen.

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this