我正在设计一个使用DirectX 11 API的游戏引擎,特别是使用延迟上下文。其基本思想是让每个设备状态都有自己的延迟上下文,然后在渲染完所有几何图形后,通过迭代每个延迟的上下文并在直接上下文中执行其命令列表来显示它。我通过使用线框着色器简单地在屏幕上绘制两个三角形来测试这一点。即使在PIX调试报告中查看,所有DirectX调用都不会返回错误,但只要调用IDXGISwapChain::Present(0,0
),整个屏幕就会变黑,然后返回。然后在屏幕右下角弹出一个错误框,指出显示驱动程序“已停止响应并成功恢复”。回顾PIX日志,我发现在PIX日志中的前后块之间有一行显示“D3D11: Removing Device
”。邮政区块中显示的返回值为DXGI_ERROR_DEVICE_REMOVED
。我不太确定该怎么做。 PIX日志如下:IDXGISwapChain :: Present导致驱动程序崩溃和设备移除
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)
如果需要其他东西,请告诉我。我没有发布代码,主要是因为它扩展了近20个独立的类,但我可以发布缓冲区内容,HLSL和逻辑背后的解释。
UPDATE:
我有所解决上述问题,部分原因很可能是由于没有设置任何着色器,没有索引缓冲区,没有顶点缓冲区,并没有固定的缓冲区。原来的问题仍然没有解决,但在处理这个问题时,我想到了一个新的想法。我从来没有打电话给ID3D11DeviceContext::Begin(0)
。但是,从设备状态类获取设备上下文并在该上下文中调用Begin后,最终会出现访问冲突,并将指向ID3D11DeviceContext
对象的指针设置为零。这只发生在Begin
的呼叫中,并且移除呼叫会导致行为停止。仔细查看DirectX SDK中的示例代码,我无法找到任何明确的调用开始。这个电话是否必要?这可能看起来有点偏离主题,但如果命令列表因此而被破坏,这可能是Present
正在移除设备的原因。
相关代码:
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);
}
我想你会得到这个,如果驱动程序崩溃并重置自己,所以这可能是一个驱动程序错误...也许尝试你的代码与参考设备,试图缩小它? – jcoder 2012-03-23 20:42:49
测试参考设备中的程序并发生相同的错误。但是,我注意到了两个明显的错误:尽管创建了一个常量缓冲区,一个顶点着色器和一个像素着色器,但我从未将它们设置为该设备。因此,当运行时渲染三角形时,没有着色器代码,并且世界/视图/投影矩阵没有常量缓冲区。我已经着手解决这些错误在适当的类中。 – Alex 2012-03-26 00:39:48
如果你在这里没有得到任何答案,也许gamedev.stackexchange.com会更好,或者也许在gamedev.net的论坛? – jcoder 2012-03-26 16:42:59