如果调用RSSetScissorRects,事件上的WaitForSingleObject会导致访问冲突

时间:2016-06-20 19:11:14

标签: c++ winapi rendering access-violation directx-12

WaitForSingleObject函数导致以下错误

DrawTexturedCube.exe中0x00007FFA02794AD0(d3d12warp.dll)抛出异常:0xC0000005:访问冲突读取位置0x0000000000000000

在等待前一帧完成时。该代码取自MSDN DirectX12示例代码(https://msdn.microsoft.com/en-us/library/windows/desktop/dn899189%28v=vs.85%29.aspx)。

void D3D12RenderSystem::waitForPreviousFrame() {
    const UINT fence = fenceValue_;
    ThrowIfFailed(commandQueue_->Signal(fence.Get(), fence));
    fenceValue_++;

    if (fence_->GetCompletedValue() < fence) {
        ThrowIfFailed(fence_->SetEventOnCompletion(fence, fenceEvent_));
        WaitForSingleObject(fenceEvent_, INFINITE);
    }
    frameIndex_ = swapChain_->GetCurrentBackBufferIndex();
}

此错误仅在4个测试用例中的1个中发生。如果我从paintEvent循环中移除对以下函数的调用,则访问冲突消失(但渲染到视口的图像也是如此),该循环的结构如此处所述(https://msdn.microsoft.com/de-de/library/windows/desktop/dn903899%28v=vs.85%29.aspx)。

void D3D12CommandList::setScissorRect(const int width, const int height) {
    D3D12_RECT rectScissor = { 0.0f, //top
                               0.0f, //left
                               static_cast<LONG>(width), //right
                               static_cast<LONG>(height)}; //bottom
    commandList_->RSSetScissorRects(1, &rectScissor);
}

我使用VS2015并且调试器在所有测试用例中都没有将fenceEvent_变量显示为NULL并且反汇编显示?? ??对于所有测试用例中句柄指向的内存。我的着色器不使用几何着色器。

所以现在我有两个问题:

  1. WaitForSingleObject函数如何在4个几乎相同的测试用例中只有1个导致访问冲突?
  2. RSSetScissorRects函数和WaitForSingleObject函数如何相互关联?

1 个答案:

答案 0 :(得分:1)

好的,现在我找到错误并修复它。这是由于意外地使用常量缓冲区的描述符堆覆盖纹理缓冲区的描述符堆。因此draw命令试图访问纹理缓冲区,当然它比常量缓冲区大,因此导致分割错误。通过不设置剪刀矩形,也没有执行绘制调用,因此没有错误。