-2

The WaitForSingleObject function causes the following error

Exception thrown at 0x00007FFA02794AD0 (d3d12warp.dll) in DrawTexturedCube.exe: 0xC0000005: Access violation reading location 0x0000000000000000

while waiting for the previous frame to complete. The Code is taken from the MSDN DirectX12 Example Code (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();
}

This error does only occur in 1 of 4 test cases. The access violation disappears (but so does the image rendered to the Viewport) if I remove the call to the following function from the paintEvent loop, which is structured as described here (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);
}

I'm using VS2015 and the debugger isn't showing the fenceEvent_ variable as NULL in all test cases and the disassembly shows ?? ?? for the memory where the handle points to in all test cases. My shaders don't use geometry shaders.

So now I have 2 questions:

  1. How can the WaitForSingleObject function lead to an access violation in only 1 out of 4 nearly identical test cases?
  2. How are the RSSetScissorRects function and the WaitForSingleObject function related to each other?
hechth
  • 95
  • 11
  • Likeliest suspect is `fenceEvent_` is NULL; can you check this? – Richard Critten Jun 20 '16 at 19:15
  • Checked it in Debugger already, is not null in both cases, but disassembly only gives ?? ?? as values in both test cases. – hechth Jun 20 '16 at 19:21
  • 3
    Please show a MCVE – David Heffernan Jun 20 '16 at 19:26
  • 1
    A handle is an opaque data type. A debugger cannot show you object information for any given handle (unless you issue special commands in a debugger that knows kernel objects, like WinDbg). – IInspectable Jun 20 '16 at 22:11
  • `disassembly only gives ?? ??` - this is usually an indication that the memory pointed to is no longer allocated. – 500 - Internal Server Error Jun 20 '16 at 23:27
  • 2
    @RichardCritten: more likely the `this` pointer that is used to access `fenceEvent_` is NULL, not `fenceEvent_` itself. `WaitForSingleObject()` does not crash if you pass it a NULL handle, it will simply fail with an `ERROR_INVALID_HANDLE` error. – Remy Lebeau Jun 21 '16 at 00:01
  • @IInspectable: Thanks, I didn't know that. I use the VS2015 debugger. – hechth Jun 21 '16 at 06:42
  • Why are you using a warp device to start with ? The warp device is a software rasterizer and not the GPU. – galop1n Jun 22 '16 at 03:33
  • @galop1n: It also fails on the GPU, since the same error occurs. The other test cases run with Software and Hardware rasterizer. – hechth Jun 22 '16 at 06:24
  • @TioZ Ok, so it is intentional. Do you run with the debug layer on, in the case something wrong happen, prior to your crash, it may log useful information. You have to call `D3D12GetDebugInterface` then `EnableDebugLayer` prior to the device creation. One way to crash while calling API on a command list would be if one call to `Close` failed a validation, in that case, the command list is stale and can never be reuse again. – galop1n Jun 22 '16 at 17:09

1 Answers1

1

Ok, so now I located the Error and fixed it. It was due to accidently overriding the descriptor heap of the texture buffer with the descriptor heap of the constant buffer. So the draw command tried to access the texture buffer, which was of course way bigger than the constant buffer and therefore resulted in the segmentation error. By not setting the scissor rectangle, also no draw call was executed, therefore no error.

hechth
  • 95
  • 11