I am designing a game engine that makes use of the DirectX 11 API, in particular, the use of deferred contexts. The basic idea is to have each and every device state given its own deferred context, and then, after all geometry has been rendered, to display it by iterating over every deferred context and executing its command list on the immediate context. I tested this by simply drawing two triangles onto the screen using a wireframe shader and nothing else. All DirectX calls return no errors, even when viewed in a PIX debug report, but as soon as IDXGISwapChain::Present(0,0
) is called, the entire screen goes black and then returns. An error box then pops up in the lower right corner of the screen stating that the display driver "has stopped responding and successfuly recovered". Reviewing the PIX log, I found a single line stating "D3D11: Removing Device
" between the pre and post blocks of the call in the PIX log. The return value shown in the post block is DXGI_ERROR_DEVICE_REMOVED
. I'm not quite sure what to make of this. The PIX log is as follows:
Frame 000001 ........PRE: CreateDXGIFactory1(IID_IDXGIFactory1, 0x012E1E2C)
Frame 000001 ............PRE: AddObject(DXGI Factory, 0x0040FF98, 0x0065B810)
Frame 000001 ............POST: <TRUE> AddObject(DXGI Factory, 0x0040FF98, 0x0065B810)
Frame 000001 ........POST: <S_OK> CreateDXGIFactory1(IID_IDXGIFactory1, 0x012E1E2C)
Frame 000001 ........PRE: D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 32, NULL, 0, 7, 0x0019F444, 0x012E1E5C, 0x012E1E54, 0x012E1E58, 0x012E1E60)
Frame 000001 ............PRE: AddObject(D3D11 Device, 0x03666B38, 0x009E9940)
Frame 000001 ............POST: <TRUE> AddObject(D3D11 Device, 0x03666B38, 0x009E9940)
Frame 000001 ............PRE: AddObject(DXGI Factory, 0x03666B98, 0x0065BAB0)
Frame 000001 ............POST: <TRUE> AddObject(DXGI Factory, 0x03666B98, 0x0065BAB0)
Frame 000001 ............PRE: AddObject(DXGI Adapter, 0x03666BE8, 0x0065C940)
Frame 000001 ............POST: <TRUE> AddObject(DXGI Adapter, 0x03666BE8, 0x0065C940)
Frame 000001 ............PRE: AddObject(DXGI Device, 0x03666C40, 0x009E9718)
Frame 000001 ............POST: <TRUE> AddObject(DXGI Device, 0x03666C40, 0x009E9718)
Frame 000001 ............PRE: AddObject(DXGI Swap Chain, 0x03666CA0, 0x009EF940)
Frame 000001 ............POST: <TRUE> AddObject(DXGI Swap Chain, 0x03666CA0, 0x009EF940)
Frame 000001 ............PRE: AddObject(DXGI Surface, 0x03666D38, 0x009EFB9C)
Frame 000001 ............POST: <TRUE> AddObject(DXGI Surface, 0x03666D38, 0x009EFB9C)
Frame 000001 ............PRE: AddObject(D3D11 Texture2D, 0x03666D98, 0x009EFBD4)
Frame 000001 ............POST: <TRUE> AddObject(D3D11 Texture2D, 0x03666D98, 0x009EFBD4)
Frame 000001 ............PRE: AddObject(D3D11 Device Context, 0x036C1E08, 0x009F1840)
Frame 000001 ............POST: <TRUE> AddObject(D3D11 Device Context, 0x036C1E08, 0x009F1840)
Frame 000001 ........POST: <S_OK> D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 32, NULL, 0, 7, 0x0019F444, 0x012E1E5C, 0x012E1E54, 0x012E1E58, 0x012E1E60)
Frame 000001 ........PRE: <this=0x03666b38>ID3D11Device::CheckFeatureSupport(D3D11_FEATURE_THREADING, 0x0019F2C8, 8)
Frame 000001 ........POST: <S_OK><this=0x03666b38> ID3D11Device::CheckFeatureSupport(D3D11_FEATURE_THREADING, 0x0019F2C8, 8)
Frame 000001 ........PRE: <this=0x03666b38>ID3D11Device::CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, 0x0019F2BC, 4)
Frame 000001 ........POST: <S_OK><this=0x03666b38> ID3D11Device::CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, 0x0019F2BC, 4)
Frame 000001 ........PRE: <this=0x03666b38>ID3D11Device::CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, 0x0019F2B0)
Frame 000001 ........POST: <S_OK><this=0x03666b38> ID3D11Device::CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, 0x0019F2B0)
Frame 000001 ........PRE: <this=0x03666b38>ID3D11Device::GetCreationFlags()
Frame 000001 ........POST: <32><this=0x03666b38> ID3D11Device::GetCreationFlags()
Frame 000001 ........PRE: <this=0x03666b38>ID3D11Device::CreateDeferredContext(0, 0x0FB34BA4)
Frame 000001 ............PRE: AddObject(D3D11 Device Context, 0x036C9C58, 0x009F7C38)
Frame 000001 ............POST: <TRUE> AddObject(D3D11 Device Context, 0x036C9C58, 0x009F7C38)
Frame 000001 ........POST: <S_OK><this=0x03666b38> ID3D11Device::CreateDeferredContext(0, 0x0FB34BA4)
Frame 000001 ........PRE: <this=0x03666b38>ID3D11Device::CreateRasterizerState(0x0019F3F8, 0x0FB34BA0)
Frame 000001 ............PRE: AddObject(D3D11 Rasterizer State, 0x03666E38, 0x009F0A98)
Frame 000001 ............POST: <TRUE> AddObject(D3D11 Rasterizer State, 0x03666E38, 0x009F0A98)
Frame 000001 ........POST: <S_OK><this=0x03666b38> ID3D11Device::CreateRasterizerState(0x0019F3F8, 0x0FB34BA0)
Frame 000001 ........PRE: <this=0x03666b38>ID3D11Device::CreateInputLayout(0x0FB50158, 2, 0x009F0368, 568, 0x0FB35B3C)
Frame 000001 ............PRE: AddObject(D3D11 Input Layout, 0x03666EB0, 0x009F0B18)
Frame 000001 ............POST: <TRUE> AddObject(D3D11 Input Layout, 0x03666EB0, 0x009F0B18)
Frame 000001 ........POST: <S_OK><this=0x03666b38> ID3D11Device::CreateInputLayout(0x0FB50158, 2, 0x009F0368, 568, 0x0FB35B3C)
Frame 000001 ........PRE: <this=0x03666b38>ID3D11Device::CreateSamplerState(0x0019F418, 0x0019F46C)
Frame 000001 ............PRE: AddObject(D3D11 Sampler State, 0x03666F10, 0x009EF8D8)
Frame 000001 ............POST: <TRUE> AddObject(D3D11 Sampler State, 0x03666F10, 0x009EF8D8)
Frame 000001 ........POST: <S_OK><this=0x03666b38> ID3D11Device::CreateSamplerState(0x0019F418, 0x0019F46C)
Frame 000001 ........PRE: <this=0x03666f10>ID3D11SamplerState::AddRef()
Frame 000001 ........POST: <2><this=0x03666f10> ID3D11SamplerState::AddRef()
Frame 000001 ........PRE: <this=0x03666b38>ID3D11Device::AddRef()
Frame 000001 ........POST: <8><this=0x03666b38> ID3D11Device::AddRef()
Frame 000001 ........PRE: <this=0x03666b38>ID3D11Device::CreateVertexShader(0x009F0368, 568, NULL, 0x0FB3046C)
Frame 000001 ............PRE: AddObject(D3D11 Vertex Shader, 0x03666F60, 0x009EFCB4)
Frame 000001 ............POST: <TRUE> AddObject(D3D11 Vertex Shader, 0x03666F60, 0x009EFCB4)
Frame 000001 ........POST: <S_OK><this=0x03666b38> ID3D11Device::CreateVertexShader(0x009F0368, 568, NULL, 0x0FB3046C)
Frame 000001 ........PRE: <this=0x03666b38>ID3D11Device::CreatePixelShader(0x009F0958, 244, NULL, 0x0FB30470)
Frame 000001 ............PRE: AddObject(D3D11 Pixel Shader, 0x03666FB8, 0x009E2CF4)
Frame 000001 ............POST: <TRUE> AddObject(D3D11 Pixel Shader, 0x03666FB8, 0x009E2CF4)
Frame 000001 ........POST: <S_OK><this=0x03666b38> ID3D11Device::CreatePixelShader(0x009F0958, 244, NULL, 0x0FB30470)
Frame 000001 ........PRE: <this=0x03666b38>ID3D11Device::Release()
Frame 000001 ........POST: <9><this=0x03666b38> ID3D11Device::Release()
Frame 000001 ........PRE: <this=0x03666b38>ID3D11Device::CreateBuffer(0x0019F914, NULL, 0x0FB364A8)
Frame 000001 ............PRE: AddObject(D3D11 Buffer, 0x036656F0, 0x009E2E14)
Frame 000001 ............POST: <TRUE> AddObject(D3D11 Buffer, 0x036656F0, 0x009E2E14)
Frame 000001 ........POST: <S_OK><this=0x03666b38> ID3D11Device::CreateBuffer(0x0019F914, NULL, 0x0FB364A8)
Frame 000001 ........PRE: <this=0x03666b38>ID3D11Device::CreateBuffer(0x0019F914, NULL, 0x0FB3E1B0)
Frame 000001 ............PRE: AddObject(D3D11 Buffer, 0x03665778, 0x009F03D4)
Frame 000001 ............POST: <TRUE> AddObject(D3D11 Buffer, 0x03665778, 0x009F03D4)
Frame 000001 ........POST: <S_OK><this=0x03666b38> ID3D11Device::CreateBuffer(0x0019F914, NULL, 0x0FB3E1B0)
Frame 000001 ........PRE: <this=0x03666b38>ID3D11Device::CreateBuffer(0x0019F914, NULL, 0x0FB46E58)
Frame 000001 ............PRE: AddObject(D3D11 Buffer, 0x03665800, 0x009E3994)
Frame 000001 ............POST: <TRUE> AddObject(D3D11 Buffer, 0x03665800, 0x009E3994)
Frame 000001 ........POST: <S_OK><this=0x03666b38> ID3D11Device::CreateBuffer(0x0019F914, NULL, 0x0FB46E58)
Frame 000001 ........PRE: <this=0x036c1e08>ID3D11DeviceContext::RSSetViewports(1, 0x012E1EBC)
Frame 000001 ........POST: <><this=0x036c1e08> ID3D11DeviceContext::RSSetViewports(1, 0x012E1EBC)
Frame 000001 ........PRE: <this=0x036c9c58>ID3D11DeviceContext::IASetInputLayout(0x03666EB0)
Frame 000001 ........POST: <><this=0x036c9c58> ID3D11DeviceContext::IASetInputLayout(0x03666EB0)
Frame 000001 ........PRE: <this=0x036c9c58>ID3D11DeviceContext::AddRef()
Frame 000001 ........POST: <2><this=0x036c9c58> ID3D11DeviceContext::AddRef()
Frame 000001 ........PRE: <this=0x036c9c58>ID3D11DeviceContext::DrawIndexed(6, 0, 0)
Frame 000001 ........POST: <><this=0x036c9c58> ID3D11DeviceContext::DrawIndexed(6, 0, 0)
Frame 000001 ........PRE: <this=0x036c9c58>ID3D11DeviceContext::Release()
Frame 000001 ........POST: <1><this=0x036c9c58> ID3D11DeviceContext::Release()
Frame 000001 ........PRE: <this=0x036c9c58>ID3D11DeviceContext::FinishCommandList(FALSE, 0x0019F928)
Frame 000001 ............PRE: AddObject(D3D11 Command List, 0x03665888, 0x009E3A94)
Frame 000001 ............POST: <TRUE> AddObject(D3D11 Command List, 0x03665888, 0x009E3A94)
Frame 000001 ........POST: <S_OK><this=0x036c9c58> ID3D11DeviceContext::FinishCommandList(FALSE, 0x0019F928)
Frame 000001 ........PRE: <this=0x036c1e08>ID3D11DeviceContext::ExecuteCommandList(0x03665888, FALSE)
Frame 000001 ........POST: <><this=0x036c1e08> ID3D11DeviceContext::ExecuteCommandList(0x03665888, FALSE)
Frame 000001 ........PRE: <this=0x03666ca0>IDXGISwapChain::Present(0, 1)
Frame 000001 ........POST: <S_OK><this=0x03666ca0> IDXGISwapChain::Present(0, 1)
Frame 000001 ........PRE: <this=0x03666ca0>IDXGISwapChain::Present(0, 0)
D3D11: Removing Device.
Frame 000001 ........POST: <DXGI_ERROR_DEVICE_REMOVED><this=0x03666ca0> IDXGISwapChain::Present(0, 0)
Frame 000001 ....POST: <> Frame(1)
If anything else is required, let me know. I haven't posted code mainly because it extends over almost 20 separate classes, but I can post buffer contents, HLSL, and explanations behind the logic.
UPDATE:
I have somewhat solved the problem above, part of the reason was most likely due to not having set any shaders, no index buffers, no vertex buffers, and no constant buffers. The original problem is still not solved, but a new thought came to me while working on this. I never called ID3D11DeviceContext::Begin(0)
. However, upon obtaining the device context from the device state class and calling Begin on that context, I end up with an access violation and the pointer to the ID3D11DeviceContext
object being set to zero. This only happens on a call to Begin
, and removing the call causes the behavior to stop. Looking through the example code in the DirectX SDK, I can't find an explicit call to begin at any time. Is this call necessary? This might seem a little off topic, but if the command list is mangled because of it, this might be the reason Present
is removing the device.
relevant code:
if(FAILED(devstate->BeginDraw(inlayout,&dc)))
{
return ACERROR_ALREADYDRAWING; //error handling block.
}
//dc->Begin(0); //access violation: error accessing location 0x00000024
for(UINT i=Shader_Vertex;i<Shader_Count;i++)
{
//set all relevant shaders to the device.
(dc->*(vtbls[i].ShaderSet))(shaders[i],0,0);
}
After having reviewed the code over the past 6 days, I've made a strange discovery: despite all of my knowledge in DirectX 9.0c, coding in DirectX 11 is.... different. After finding several stupid mistakes in the code, I managed to fix the error on the hardware device, but strangely, not on the ref device. I'm currently looking into the DirectX 11 pipeline changes before attempting to figure out why I can clear the background extremely easily, but trying to draw a triangle with a deferred context doesn't work at all.
Thanks for the suggestions from everyone who tried to help.
User contributions licensed under CC BY-SA 3.0