C++ 如果调用RSSetsCisorRects,事件上的WaitForSingleObject将导致访问冲突

C++ 如果调用RSSetsCisorRects,事件上的WaitForSingleObject将导致访问冲突,c++,winapi,rendering,access-violation,directx-12,C++,Winapi,Rendering,Access Violation,Directx 12,WaitForSingleObject函数导致以下错误 在DrawTexturedCube.exe中的0x00007FFA02794AD0(d3d12warp.dll)处引发异常:0xC0000005:访问冲突读取位置0x0000000000000000 在等待上一帧完成时。代码取自MSDN DirectX12示例代码() void D3D12RenderSystem::waitForPreviousFrame(){ consuint fence=fenceValue_u2;; ThrowIfF

WaitForSingleObject函数导致以下错误

在DrawTexturedCube.exe中的0x00007FFA02794AD0(d3d12warp.dll)处引发异常:0xC0000005:访问冲突读取位置0x0000000000000000

在等待上一帧完成时。代码取自MSDN DirectX12示例代码()

void D3D12RenderSystem::waitForPreviousFrame(){
consuint fence=fenceValue_u2;;
ThrowIfFailed(commandQueue->Signal(fence.Get(),fence));
fenceValue_uz++;
如果(围栏->GetCompletedValue()设置事件完成(围栏,围栏事件));
WaitForSingleObject(fenceEvent,无限);
}
frameIndex=交换链->GetCurrentBackBufferIndex();
}
此错误仅在4个测试用例中的1个出现。如果我从paintEvent循环中删除对以下函数的调用,访问冲突就会消失(但渲染到视口的图像也会消失),该循环的结构如下所述()

void D3D12CommandList::setScissorRect(常量整型宽度,常量整型高度){
D3D12_RECT rectscrissor={0.0f,//顶部
0.0f,//左
静态投影(宽度),//右
静态(高度)};//底部
commandList->RSSetScissorRects(1,&rectScissor);
}
我使用的是VS2015,调试器没有在所有测试用例中将fenceEvent_uuu变量显示为NULL,反汇编显示为??对于所有测试用例中句柄指向的内存。我的着色器不使用几何体着色器

现在我有两个问题:

  • WaitForSingleObject函数如何在4个几乎相同的测试用例中仅1个导致访问冲突
  • RSSetsCisorRects函数和WaitForSingleObject函数之间的关系如何

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

    最可能的可疑对象是
    fenceEvent\uu
    为空;你们能检查一下吗?已经在调试器中检查过了,在这两种情况下都不是空的,但反汇编只给出??作为两个测试用例中的值。请显示MCVEA句柄是不透明的数据类型。调试器无法向您显示任何给定句柄的对象信息(除非您在了解内核对象的调试器中发出特殊命令,如WinDbg)。@RichardCriten:更有可能的是,用于访问
    fenceEvent\uuuuu
    指针为空,而不是
    fenceEvent\uuuu
    本身
    WaitForSingleObject()
    不会崩溃。如果向它传递一个空句柄,它将失败,并出现
    错误\u无效\u句柄
    错误。
    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();
    }
    
    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);
    }