D3D12 project: dereferencing a nullptr - c++

I am working with the Microsoft samples from their GitHub page and even though my code is based off theirs I am not reaching the same result.
Both projects have these ComPtrs yet in mine they all are null (0x0000000000000000) while in the sample they work perfectly fine.
ComPtr<IDXGISwapChain3> m_swapChain;
ComPtr<ID3D12Device> m_device;
ComPtr<ID3D12Resource> m_renderTargets[FrameCount];
ComPtr<ID3D12CommandAllocator> m_commandAllocator;
ComPtr<ID3D12CommandQueue> m_commandQueue;
ComPtr<ID3D12DescriptorHeap> m_rtvHeap;
ComPtr<ID3D12PipelineState> m_pipelineState;
ComPtr<ID3D12GraphicsCommandList> m_commandList;
Specifically this line causes the debugger to break.
ThrowIfFailed(m_device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_commandQueue)));
Edit: My code was incorrectly creating m_device which caused the error.

My guess is that you are getting a failed HRESULT back from CreateCommandQueue. You should set the debugger to break on exceptions (see MSDN). Alternatively, you can rewrite it to:
HRESULT hr = m_device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_commandQueue));
ThrowIfFailed(hr);
And set a debug break-point on the HRESULT hr = ... line.
As someone noted, make sure you have checked for all possible failure conditions before this point. For some robust code for creating a Direct3D 12 device, see DeviceResources or the VS Direct3D 12 Game templates

Related

Exception thrown: read access violation. std::shared_ptr<>::operator-><,0>(...)->**** was 0xFFFFFFFFFFFFFFE7

Good afternoon to all! I am writing a game engine using OpenGL + Win32 / GLFW. Therefore, I will say the project is large, but I have a problem that has led me to a dead end and I can't understand what the problem is. The problem is that I have a shared_ptr<Context> in the 'windows' class (it is platform-based) that is responsible for the context (GL, D3D). And everything works fine when I launch the application, everything is drawn normally, but when I start entering the cursor into the window, a crash occurs when any function calls from context, in my case is:
context->swapBuffers();
Here a crash:
std::shared_ptr<Context>::operator-><Context,0>(...)->**** was 0xFFFFFFFFFFFFFFE7.
Then I got into the callstack and saw that the context-> itself is non-zero, so the function should be called.
Then I searched for a long time for the problem and found that when I remove the Win32 message processing code, and when I remove it, errors do not occur when calling a function from context->. I removed everything unnecessary from the loop and left only the basic functions and tried to run it like this, because I thought that some other functions inside were causing this problem, but no.
while (PeekMessageW(&msg, NULL, NULL, NULL, PM_REMOVE) > 0) {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
That is, when I delete TranslateMessage() and DispatchMessage(), the error goes away. And then I finally got confused i.e I don't understand what is happening. And then I thought that maybe somehow the operating system itself affects that pointer, prohibits reading or something like that.
And then I paid attention to __vtptr in the call stack, and noticed that it is nullptr, and moreover it has the void** type. And also the strangest thing is that in the error I have ->**** was 0xffffffffffffffc7 as many as four consecutive pointers. What is it?
I understand I practically didn't throw off the code, because I have a big project and I think it doesn't make sense to throw everything, so I tried to explain the problem by roughly showing what is happening in my code. I will be grateful to everyone who will help :)

DX12 Initialization Fail VS2019

I have done the init steps in DX10/11/12 many times before, all of a sudden in VS2019 DX12 will not create anything besides the following objects: ID3D12Debug, ID3D12InfoQueue, ID3D12Device2.
Even a straight creation of command queue fails:
bool DX12ObjectFactory::CreateCommandQueue(ID3D12Device* pDevice, __out
ID3D12CommandQueue** ppCmdQueue, const D3D12_COMMAND_QUEUE_DESC& queueCreateDesc)
{
OnFailedThrow(pDevice->CreateCommandQueue(&queueCreateDesc,
IID_PPV_ARGS(&*ppCmdQueue)));
return true;
}
HRESULT message is:
hr = 0x00000108 : An open/create operation completed while an oplock break is underway.
Error code lookup points to: ERROR_TOO_MANY_POSTS 298 (0x12A)
Weird thing is that things were working a few days ago, maybe a Windows update broke it...
Thanks
D3D12_COMMAND_QUEUE_DESC was initialized properly, issues seemed to be use of IID_PPV_ARGS, as it was fine with the old way of using IID_ID3D12CommandQueue, (void**)&(*ppCmdQueue).
Also my swapchain issue I forgot to initialize buffer count with a value >= 2.

Visual Studio Graphics Debugger throws read access violation exception

I'm writing a simple renderer using the d3d11 library in Visual Studio 2019 and it builds and runs fine. However when I try running the Graphics Debugger it immediately throws a read access violation for address 0x0000000000000000 ( which is clearly incorrect ).
The exception is thrown from the DXCaptureReplay dll on the line
DeviceContext.PSSetShader(InShaderToBind.Shader.PS, NULL, 1);
Where InShaderToBind.Shader.PS is a pointer to ID3D11PixelShader
It got the most weird when I out of a lack of ideas tried
int X = 0;
ID3D11ClassInstance* FakedClassInstance = reinterpret_cast<ID3D11ClassInstance*>(&X);
DeviceContext.PSSetShader(InShaderToBind.Shader.PS, &FakedClassInstance, 1);
As this will make the exception not throw until I try to capture a frame ( Which I guess makes sense as that pointer will only be valid for the scope where X is still valid )
The MSDN documentation states that NULL should be a perfectly valid argument to pass to PSSetShader ( as noted here: https://learn.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-id3d11devicecontext-pssetshader )
Any ideas for what might be going wrong?
( If I comment out PSSetShader the exception is not thrown and I can take captures )
If you enable the Direct3D Debug Device, you would see in your debug output window:
D3D11 CORRUPTION: ID3D11DeviceContext::PSSetShader: Second parameter (ppClassInstances) corrupt or unexpectedly NULL. [ MISCELLANEOUS CORRUPTION #14: CORRUPTED_PARAMETER2]
NULL (or better yet nullptr) is fine for ppClassInstances only if NumClassInstances is 0. Try:
DeviceContext.PSSetShader(InShaderToBind.Shader.PS, NULL, 0);
Generally you should make sure your program runs without emitting ERROR or CORRUPTION messages from the debug layer before attempting to use PIX or the VSGS tool.
See Microsoft Docs and this blog post.

C++ COM ATL VariantChangeType causes WSH to crash

I have following line of code in my COM ATL project which causes WSH to crash:
Result = VariantChangeType(&Variant, &Variant, VARIANT_NOUSEROVERRIDE, VT_UINT);
When above function gets called prior to crash, Variant's type is VT_BSTR, that's why I used VARIANT_NOUSEROVERRIDE flag. I tried removing flag with no success.
What is wrong here for WSH to crash? I am sure that this is the line that causes the crash because message box which is prior to this line is displaying but message box after this line isn't displaying. Then Windows says:
Microsoft ® Windows Based Script Host has stopped working
Is my syntax wrong here?
I fixed this issue by using CComVariant::ChangeType instead of using VariantChangeType function like below:
CComVariant CV = Variant;
HRESULT Result = CV.ChangeType(VT_I2);

How do I programmatically find why a DLL fails to load?

My C++ program calls LoadLibraryEx() to load a third party DLL. The result is a null handle - it fails to load. A call to GetLastError() returns zero afterwards which isn't of much use but at least it's not a missing DLL file.
The code goes something like this:
HINSTANCE instance = ::LoadLibraryExW(
path, 0, LOAD_WITH_ALTERED_SEARCH_PATH );
if (instance == 0)
{
DWORD lastError = GetLastError();
LOG( "Failed to load, error code is " +
LastErrorAsString( lastError ));
return E_FAIL;
}
I cannot access that machine - I can only deploy code there and observe logs uploaded into network storage.
How would I programmatically find why the DLL fails to load?
Probably your dll can be found but it has a dependency on a dll that cannot found on the remote machine.
If you cannot use Dependency Walker then you can try to use techniques as described in articles such as this:
How to determine a windows executables DLL dependencies programatically?
Okay, so I checked better - and indeed there was another WinAPI call which caused "last error" to be overwritten after LoadLibraryEx(). It was hidden deep inside several layers of C++ helper objects so I didn't notice it earlier. So it was a bug in the caller code and the real "last error" was non-zero.
It looks like the problem is likely to be third-party software that has installed a hook or other anti-virus measure, the hook might be buggy and not setting the correct last error code.
As a troubleshooting measure, you should try LdrLoadDll instead of LoadLibraryEx.
Note that this is an undocumented internal function, so you might prefer not to use it in production code, but it would be a useful troubleshooting step as it should produce a more useful error code.