Flickering, but using double buffer

Started by
4 comments, last by Zaoshi Kaba 10 years, 9 months ago

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;
Advertisement

I fail to see why it would flicker. Constant buffer shouldn't cause such issue. Any chance you could post whole solution, or at least binary files? If it doesn't happen on other PCs it could be driver problem.

I tested it now with the reference driver - and it didn't flicker!

(Great first touch with d3d11! :()

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);


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?

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.

This topic is closed to new replies.

Advertisement