/* attempt to deal with prototype, bootstrap, jquery conflicts */ /* for dropdown menus */

\$75

### Image of the Day Submit

IOTD | Top Screenshots

## Direct3D11 dev->CreateVertexShader() crashes the program.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

15 replies to this topic

### #1RoundPotato  Members

Posted 01 May 2013 - 09:01 PM

Hello there,

I've pinned the crash down to its position and it turned out to be:

dev->CreateVertexShader(vBlob->GetBufferPointer(),vBlob->GetBufferSize(),NULL,&vs);

It is inside "void initPipeline()"...

From:

#include <windows.h>
#include <windowsx.h>
#include <d3d11.h>
#include <d3dcompiler.h>

#pragma comment(lib,"d3d11.lib")
#pragma comment(lib,"d3dcompiler.lib")

#define SCREEN_WIDTH 1366
#define SCREEN_HEIGHT 786

// COM pointers
ID3D11Device *dev;
ID3D11DeviceContext *devCon;
IDXGISwapChain *sc;
ID3D11RenderTargetView *backBuffer;
ID3D11Buffer *vBuffer;
ID3D11InputLayout *il;

// VERTEX struct
struct VERTEX
{
FLOAT x,y,z;
FLOAT color[4];
};

void renderFrame()
{
float color[4] = {0.0,0.2,0.4,1.0};
devCon->ClearRenderTargetView(backBuffer,color);
/*
// set Vertex buffers
UINT size = sizeof(VERTEX);
UINT offset = 0;
devCon->IASetVertexBuffers(0,1,&vBuffer,&size,&offset);

// set primitives rendering style
devCon->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

// draw vertex onto back buffer
devCon->Draw(3,0);
*/
// swap buffers
sc->Present(0,0);
}

void initPipeline()
{
ID3D10Blob *vBlob,*pBlob;

/*
*/
/*
// Describe Input Layout
D3D11_INPUT_ELEMENT_DESC ied[] =
{
{"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0},
{"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,D3D11_APPEND_ALIGNED_ELEMENT,D3D11_INPUT_PER_VERTEX_DATA,0}
};

// Create Input Layout
dev->CreateInputLayout(ied,2,vBlob->GetBufferPointer(),vBlob->GetBufferSize(),&il);

// set Input Layout
devCon->IASetInputLayout(il);
*/
}

void initGraphics()
{
// create a triangle using the VERTEX struct
VERTEX verts[] =
{
{0.0f, 0.5f, 0.0f, (1.0f, 0.0f, 0.0f, 1.0f)},
{0.45f, -0.5, 0.0f, (0.0f, 1.0f, 0.0f, 1.0f)},
{-0.45f, -0.5f, 0.0f, (0.0f, 0.0f, 1.0f, 1.0f)}
};

// create buffer
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd,sizeof(D3D11_BUFFER_DESC));

bd.Usage = D3D11_USAGE_DYNAMIC;
bd.ByteWidth = sizeof(VERTEX)*3;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;

dev->CreateBuffer(&bd,NULL,&vBuffer);

D3D11_MAPPED_SUBRESOURCE msr;
memcpy(msr.pData,verts,sizeof(verts));
devCon->Unmap(vBuffer,NULL);
}

void initD3D(HWND hWnd)
{
DXGI_SWAP_CHAIN_DESC scd;
ZeroMemory(&scd,sizeof(DXGI_SWAP_CHAIN_DESC));

scd.BufferCount = 1;
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
scd.BufferDesc.Width = SCREEN_WIDTH;
scd.BufferDesc.Height = SCREEN_HEIGHT;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scd.OutputWindow = hWnd;
scd.SampleDesc.Count = 4;
scd.Windowed = TRUE;
scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

D3D11CreateDeviceAndSwapChain(NULL,D3D_DRIVER_TYPE_HARDWARE,NULL,NULL,NULL,NULL,D3D11_SDK_VERSION,&scd,&sc,&dev,NULL,&devCon);

ID3D11Texture2D *t2D;
sc->GetBuffer(0,__uuidof(ID3D11Texture2D),(LPVOID*)&t2D);
dev->CreateRenderTargetView(t2D,NULL,&backBuffer);
t2D->Release();
devCon->OMSetRenderTargets(1,&backBuffer,NULL);

/* crappy viewport
D3D11_VIEWPORT vp;
ZeroMemory(&vp,sizeof(D3D11_VIEWPORT));

vp.TopLeftX = 0;
vp.TopLeftY = 0;
vp.Width = SCREEN_WIDTH;
vp.Height = SCREEN_HEIGHT;
*/
}

void cleanD3D()
{
// turn off FullScreen
sc->SetFullscreenState(FALSE,NULL);

// release COM objects' resources
il->Release();
vBuffer->Release();
vs->Release();
ps->Release();
dev->Release();
devCon->Release();
backBuffer->Release();
sc->Release();
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}

// return default-managed values
return DefWindowProc(hWnd,msg,wParam,lParam);
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lCmdLIne,int nCmdShow)
{
WNDCLASSEX wc;
ZeroMemory(&wc,sizeof(WNDCLASSEX));

wc.cbSize = sizeof(WNDCLASSEX);
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.style = CS_HREDRAW | CS_VREDRAW;
//wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = L"WindowClass1";

RegisterClassEx(&wc);

RECT wRect = {0,0,SCREEN_WIDTH,SCREEN_HEIGHT};
HWND hWnd = CreateWindowEx(NULL,L"WindowClass1",L"MY MEGA WINDOW",WS_OVERLAPPEDWINDOW,0,0,wRect.right - wRect.left,wRect.bottom - wRect.top,NULL,NULL,hInstance,NULL);
ShowWindow(hWnd,SW_SHOWMAXIMIZED);

initD3D(hWnd);
initPipeline();
//initGraphics();

MSG msg = {0};

while(true)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if(msg.message == WM_QUIT) break;
}
else
{
renderFrame();
// 50 FPS  (1000/20)
Sleep(20);
}
}

cleanD3D();

return msg.wParam;
}


Both Pixel and Vertex Shader creation crashed the program, I don't even know what to think. Anyone has any ideas ?

### #2Zaoshi Kaba  Members

Posted 02 May 2013 - 02:36 AM

Did shader compile successfully? I cannot see other reason why it'd crash.

### #3Martins Mozeiko  Members

Posted 02 May 2013 - 02:53 AM

Most likely vBlob is NULL.

### #4unbird  Members

Posted 02 May 2013 - 03:34 AM

And yeah, like I said earlier, directxtutorial.com lacks error checking. Check the HRESULT from the compile call with the check macros (e.g. SUCCEEDED).

Also: Make sure the shader file is where your app is looking for. The working directory of Visual Studio is usually not where your exe is.

### #5RoundPotato  Members

Posted 02 May 2013 - 08:17 AM

I don't know what do you mean by Shaders compiling, but the statements where there are "compiled into blobs" is fine, it is the very creation I mentioned.

Yes the shader file is in the projects and I have copied over the necessary x86 .dll to where the .exe is (will probably ask how to get rid of it later).

I don't know how to check for those error codes you mentioned, I don't think it will be useful if it just returns true or false since it crashes on that statement anyway.

Please see attached videos of the crash and debug.

### #6RoundPotato  Members

Posted 04 May 2013 - 11:01 AM

Bump.

### #7RoundPotato  Members

Posted 06 May 2013 - 12:01 PM

Guys, Have I said something wrong or does nobody know for real ?

### #8Zaoshi Kaba  Members

Posted 06 May 2013 - 03:42 PM

Those videos show nothing we could use. it would crash only if shader didn't compile successfully (assuming your code is like the one you posted - without error checking).

### #9RyanMm  Members

Posted 07 May 2013 - 07:57 AM

Try

ID3D10Blob *VS, *PS;



ID3D10Blob *vBlob,*pBlob;


See if that works.

​Actually nevermind that just retried your code and it worked fine for me, although it didn't first time around and as of yet i can't see why.

Edited by RyanMm, 07 May 2013 - 08:05 AM.

### #10RoundPotato  Members

Posted 10 May 2013 - 04:48 PM

	if( SUCCEEDED( dev->CreateVertexShader(vBlob->GetBufferPointer(),vBlob->GetBufferSize(),NULL,&vs) ) )
else


Still crashes the same way, which I assumed the checking is useless since the call itself crashes for no reason...

Any more ideas ?

### #11unbird  Members

Posted 10 May 2013 - 05:23 PM

Good. But you don't check the shader compilation actually. Check that too. If the compilation fails, vBlob is NULL. Is it ? Because, if so, it's not even the CreateVertexShader that crashes, but dereferencing the NULL pointer with GetBufferPointer().

Also: Do you know how to use the interactive debugger ?

### #12RoundPotato  Members

Posted 10 May 2013 - 08:02 PM

Good. But you don't check the shader compilation actually. Check that too. If the compilation fails, vBlob is NULL. Is it ? Because, if so, it's not even the CreateVertexShader that crashes, but dereferencing the NULL pointer with GetBufferPointer().

I can't really check it if it's NULL or not with a "==" operator. And yes you are correct, It crashes on

vBlob->GetBufferPointer();


Also: Do you know how to use the interactive debugger ?

No

### #13unbird  Members

Posted 10 May 2013 - 08:46 PM

Hmmm, now I realize that there's even more to it, since you dont initialize your pointers to anything. Always do that IMO:
    ID3D10Blob *vBlob = NULL;

Or nullptr if you're in for modern C++.

Anyway, if not it could be anything. In debug mode they get initialized to the magic number 0xCCCCCCCC (see here).

Checking for NULL should work with
    if(vBlob == NULL)

or even (Edit: corrected)
    if(!vBlob)

Why does it not work for you ?

Sooo, the why is it NULL (because I think it is) ? If the shader compilation fails, it will be set so (Note: I don't use VS 2012 but 2010, but I can reproduce that with the old D3DX function here).

Checking for the compilation works something like this (careful, I can't really check this, I just transliterated it for you):
ID3D10Blob *vBlob = NULL;
ID3D10Blob *errors = NULL;
HRESULT hr;
if(FAILED(hr))
{
if(errors)
{
MessageBoxA(0, (LPCSTR)errors->GetBufferPointer(), "Error", 0);
errors->Release();
}
else
{
MessageBoxA(0, "Compilation failed. Is the file where it should be ?", "Error", 0);
}
exit (EXIT_FAILURE);
}

If that code does not work, maybe someone else is so kind to correct it (Edit:Found already a typo, vBlob, not pBlob. Corrected)

Interactive debugging. Well, you could hit the 'Break' button when the crash occurs, you should be on the exact line where it happens. Move your mouse over the variables and be amazed (Hint: vBlob).

Edited by unbird, 11 May 2013 - 11:21 AM.

### #14RoundPotato  Members

Posted 11 May 2013 - 09:11 AM

Thanks unbird.

It turns out to be the Shaders.hlsl file needed to be in the same directory as the "whatever.exe" and when I think about it from what you said earlier it does make sense since compilation is on runtime, right ?

But it's damn stupid, It crashed without the file at all, when I put it in the project source files (see videos) it compiled fine and even produced somekind of "Shaders.cso" file inthe directory of the "whatever.exe" yet crashed. How on earth was I supposed to know about this madness happening in a correct way even those something as being compiled

So yeah the problem is solved with moving "Shaders.hlsl" file. Thanks again.

By the way, I believe you over-thought(or forgot how C++ works) a bit when saying to check the Blob for NULL since you posted:

 if(vBlob == NULL)


Which compares the address of the pointer to NULL since we do no deference and I can't imagine the address itself ever being NULL from a typical pointer declaration when the pointer get's created under some address upon declaration and simply using it's name refers to that address.

### #15Satharis  Members

Posted 11 May 2013 - 10:57 AM

Thanks unbird.

It turns out to be the Shaders.hlsl file needed to be in the same directory as the "whatever.exe" and when I think about it from what you said earlier it does make sense since compilation is on runtime, right ?

But it's damn stupid, It crashed without the file at all, when I put it in the project source files (see videos) it compiled fine and even produced somekind of "Shaders.cso" file inthe directory of the "whatever.exe" yet crashed. How on earth was I supposed to know about this madness happening in a correct way even those something as being compiled

So yeah the problem is solved with moving "Shaders.hlsl" file. Thanks again.

By the way, I believe you over-thought(or forgot how C++ works) a bit when saying to check the Blob for NULL since you posted:

 if(vBlob == NULL)


Which compares the address of the pointer to NULL since we do no deference and I can't imagine the address itself ever being NULL from a typical pointer declaration when the pointer get's created under some address upon declaration and simply using it's name refers to that address.

His point is that you should set a pointer to NULL when you initialize it(unless it's a class member then use the initialization list.) If you check it for NULL then later, that tells you if it was ever allocated to something else. Using something like new on a pointer allocates new memory and sets it to point to that, so it would no longer be null.

If it's still set to NULL then obviously whatever call you used to allocate it earlier in the program never happened. You could also use an assert technically if it SHOULDN'T be null at that point.

That said if you don't initialize all your pointers to NULL then they're going to contain some crap value that will be interpreted as an intentional address and thus NULL will never trigger.

Edited by Satharis, 11 May 2013 - 10:58 AM.

### #16unbird  Members

Posted 11 May 2013 - 11:37 AM

Precisely. Admittedly, I made a mistake earlier, the statements are not equivalent, it should be if(!vBlob). Corrected.

Fun fact: The Visual Studio debugger will complain when using an unitialized/unused pointer (it likely checks for that that magic number). Also: It was really meant as a question or suggestion to try out yourself (because asserts or - as in this case - proper error checking are the way to go). If you want us to help you give us feedback and try our approaches. Remote debugging through a forum is not simple. Making a video is overkill, and Zaoshi Kaba was right: The video did not show more than what we already knew and suggested approaches.

Which brings me back to the other question: You really need to learn to use the interactive debugger. I already started fabricating a screenshot but heck, we're in the age of youtube

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.