Skip to main content
GameDev.net gamedev.net
🔒 Locked

DirectX - Access Violations ?

Started by Player089 Feb 24, 2011 at 6:24 PM 18 replies 10k views
Original Post
Player089
Player089
Hey guys,


im posting here because i encountered a problem that i cannot fix :/

Ive been following this tutorial in order to get a bit familiar with realtime rendering etc. However, after running my code i got some Access-Violations during runtime. I even copied&pasted the code from the website, since i thought that i might have something wrong that i simply dont see, but the result is the same.

Okay, let me post the code first and then the errors.

Code
[spoiler]

// include the basic windows header files and the Direct3D header files
#include <windows.h>
#include <windowsx.h>
#include <d3d11.h>
#include <d3dx11.h>
#include <d3dx10.h>

// include the Direct3D Library file
#pragma comment (lib, "d3d11.lib")
#pragma comment (lib, "d3dx11.lib")
#pragma comment (lib, "d3dx10.lib")

// define the screen resolution
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600

// global declarations
IDXGISwapChain *swapchain; // the pointer to the swap chain interface
ID3D11Device *dev; // the pointer to our Direct3D device interface
ID3D11DeviceContext *devcon; // the pointer to our Direct3D device context
ID3D11RenderTargetView *backbuffer; // the pointer to our back buffer
ID3D11InputLayout *pLayout; // the pointer to the input layout
ID3D11VertexShader *pVS; // the pointer to the vertex shader
ID3D11PixelShader *pPS; // the pointer to the pixel shader
ID3D11Buffer *pVBuffer; // the pointer to the vertex buffer

// a struct to define a single vertex
struct VERTEX{FLOAT X, Y, Z; D3DXCOLOR Color;};

// function prototypes
void InitD3D(HWND hWnd); // sets up and initializes Direct3D
void RenderFrame(void); // renders a single frame
void CleanD3D(void); // closes Direct3D and releases memory
void InitGraphics(void); // creates the shape to render
void InitPipeline(void); // loads and prepares the shaders

// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);


// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
HWND hWnd;
WNDCLASSEX wc;

ZeroMemory(&wc, sizeof(WNDCLASSEX));

wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = L"WindowClass";

RegisterClassEx(&wc);

RECT wr = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
AdjustWindowRect(≀, WS_OVERLAPPEDWINDOW, FALSE);

hWnd = CreateWindowEx(NULL,
L"WindowClass",
L"Our First Direct3D Program",
WS_OVERLAPPEDWINDOW,
300,
300,
wr.right - wr.left,
wr.bottom - wr.top,
NULL,
NULL,
hInstance,
NULL);

ShowWindow(hWnd, nCmdShow);

// set up and initialize Direct3D
InitD3D(hWnd);

// enter the main loop:

MSG msg;

while(TRUE)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);

if(msg.message == WM_QUIT)
break;
}

RenderFrame();
}

// clean up DirectX and COM
CleanD3D();

return msg.wParam;
}


// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
} break;
}

return DefWindowProc (hWnd, message, wParam, lParam);
}


// this function initializes and prepares Direct3D for use
void InitD3D(HWND hWnd)
{
// create a struct to hold information about the swap chain
DXGI_SWAP_CHAIN_DESC scd;

// clear out the struct for use
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));

// fill the swap chain description struct
scd.BufferCount = 1; // one back buffer
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // use 32-bit color
scd.BufferDesc.Width = SCREEN_WIDTH; // set the back buffer width
scd.BufferDesc.Height = SCREEN_HEIGHT; // set the back buffer height
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // how swap chain is to be used
scd.OutputWindow = hWnd; // the window to be used
scd.SampleDesc.Count = 4; // how many multisamples
scd.Windowed = TRUE; // windowed/full-screen mode
scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // allow full-screen switching

// create a device, device context and swap chain using the information in the scd struct
D3D11CreateDeviceAndSwapChain(NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
NULL,
NULL,
NULL,
D3D11_SDK_VERSION,
&scd,
&swapchain,
&dev,
NULL,
&devcon);


// get the address of the back buffer
ID3D11Texture2D *pBackBuffer;
swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);

// use the back buffer address to create the render target
dev->CreateRenderTargetView(pBackBuffer, NULL, &backbuffer);
pBackBuffer->Release();

// set the render target as the back buffer
devcon->OMSetRenderTargets(1, &backbuffer, NULL);


// Set the viewport
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));

viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = SCREEN_WIDTH;
viewport.Height = SCREEN_HEIGHT;

devcon->RSSetViewports(1, &viewport);

InitPipeline();
InitGraphics();
}


// this is the function used to render a single frame
void RenderFrame(void)
{
// clear the back buffer to a deep blue
devcon->ClearRenderTargetView(backbuffer, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f));

// select which vertex buffer to display
UINT stride = sizeof(VERTEX);
UINT offset = 0;
devcon->IASetVertexBuffers(0, 1, &pVBuffer, &stride, &offset);

// select which primtive type we are using
devcon->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

// draw the vertex buffer to the back buffer
devcon->Draw(3, 0);

// switch the back buffer and the front buffer
swapchain->Present(0, 0);
}


// this is the function that cleans up Direct3D and COM
void CleanD3D(void)
{
swapchain->SetFullscreenState(FALSE, NULL); // switch to windowed mode

// close and release all existing COM objects
pLayout->Release();
pVS->Release();
pPS->Release();
pVBuffer->Release();
swapchain->Release();
backbuffer->Release();
dev->Release();
devcon->Release();
}


// this is the function that creates the shape to render
void InitGraphics()
{
// create a triangle using the VERTEX struct
VERTEX OurVertices[] =
{
{0.0f, 0.5f, 0.0f, D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
{0.45f, -0.5, 0.0f, D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f)},
{-0.45f, -0.5f, 0.0f, D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f)}
};


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

bd.Usage = D3D11_USAGE_DYNAMIC; // write access access by CPU and GPU
bd.ByteWidth = sizeof(VERTEX) * 3; // size is the VERTEX struct * 3
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; // use as a vertex buffer
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; // allow CPU to write in buffer

dev->CreateBuffer(&bd, NULL, &pVBuffer); // create the buffer


// copy the vertices into the buffer
D3D11_MAPPED_SUBRESOURCE ms;
devcon->Map(pVBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms); // map the buffer
memcpy(ms.pData, OurVertices, sizeof(OurVertices)); // copy the data
devcon->Unmap(pVBuffer, NULL); // unmap the buffer
}


// this function loads and prepares the shaders
void InitPipeline()
{
// load and compile the two shaders
ID3D10Blob *VS, *PS;
D3DX11CompileFromFile(L"shaders.hlsl", 0, 0, "VShader", "vs_5_0", 0, 0, 0, &VS, 0, 0);
D3DX11CompileFromFile(L"shaders.hlsl", 0, 0, "PShader", "ps_5_0", 0, 0, 0, &PS, 0, 0);

// encapsulate both shaders into shader objects
dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);

// set the shader objects
devcon->VSSetShader(pVS, 0, 0);
devcon->PSSetShader(pPS, 0, 0);

// create the input layout object
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, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
};

dev->CreateInputLayout(ied, 2, VS->GetBufferPointer(), VS->GetBufferSize(), &pLayout);
devcon->IASetInputLayout(pLayout);
}

[/spoiler]

The errors i get after running the programm for ~ 3 sec :
Untreated exception at 0x663c11c2 in DCX11_2.exe: 0xC0000005: Accesviolation reading at position 0x00000198.[/quote]

Below( i dont know what it is, the lable says " auto" ) there are 2 things listed :

D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST 4 int[/quote]
and
devcon 0x00ca66f0 ID3D11DeviceContext * ( in red ) . [/quote]

The last call on the Call stack :
> DCX11_2.exe!RenderFrame() line 201 + 0x19 Bytes [/quote]

Which is nothing else than the function
devcon->Draw(3, 0);[/quote] in RenderFrame().

One thing that doesnt "feel" right to me, is the "Shaders.hlsl"-thing. I had to use Pixel and Vertexshader in order to render ( as the tutorial says) and were given the Shader-code by the tutorial :
struct VOut
{
float4 position : SV_POSITION;
float4 color : COLOR;
};

VOut VShader(float4 position : POSITION, float4 color : COLOR)
{
VOut output;

output.position = position;
output.color = color;

return output;
}


float4 PShader(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET
{
return color;
}


I have no idea how to read this code, the tutorial says that it's going to teach how to in the next step.
I saved this code as "Shaders.hlsl" under .../Documents/visual studios 2010/Projects/MyProjectName/MyProjectName

I don't know if these Shaders are the problem. I absolutely have no idea how to deal with Acces-violation errors, they're a total mystery for me.

At this point i would like to thank you for reading through all this and i hope that someone of you guys knows how to fix this.

Thanks in advance !

Regards
-Felix-
Buckeye
Buckeye
The particular tutorials you link to are very poor with regard to learning proper programming practice. To start with, every DirectX and windows function provides some indication of success or failure. It doesn't appear that you (or the ill-formed code on directxtutorial.com) check for any errors. Check the documentation for the function calls you make and look for return values or error indications indicating whether the function fails or succeeds. Questions for you to answer by adding error-checking code: does your window get registered? Does your window get created? Do your device and swapchain get created successfully? etc., etc.

Have you worked through the examples in the SDK? Take a look at how that code is setup, how errors are detected, etc.
Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly. You don't forget how to play when you grow old; you grow old when you forget how to play.
Player089
Player089
Hmmm. the tutorials on the site i linked to seemed very HQ to me, since everything is explained etc. However, i will do what you told me to and try to add some message boxes, to check whether or not functions got executed correctly.

I doubt that i understand anything in the SDK examples, because i guess they use tons of COM-Objects that i dont have a clue of. But i will try, eventually googeling for things that i dont know.
Buckeye
Buckeye
the tutorials on the site i linked to seemed very HQ to me[/quote]
How high quality can code be that doesn't work? I'm not saying the processes described there aren't useful. However, there's an underlying assumption there that the code will never produce errors. In my opinion, that's a very poor style of programming to be teaching anyone, particularly if it's directed at beginners.
Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly. You don't forget how to play when you grow old; you grow old when you forget how to play.
Player089
Player089
Edit : Hold it, wrong language. Second.


Edit 2 : Okay
To the "Wrong-ness" of the code : I doubt that it's actually WRONG, i guess i set something up uncorrectly. However, ure right about the thing that you should check for errors. But i can't see to find any better resource to learn DirectX from.

So, i checked all the functions that LET me check them ( that do not have a void return type). They usually return S_OK if they suceeded. All of those functions seem to have worked ( at leat my MessageBoxes tell me that ). But i cant find a way to check whether or not CreateVertexShader and CreatePixelShader succeded. According to MSDN their return type should be "D3D_OK" if they succeded. But if i check that, using this constant, my compiler tells me that he does not know this identifier. So i dont know how to check those two functions, though i guess that they worked anyways.
Buckeye
Buckeye
According to [color="#284b72"]MSDN their return type should be "D3D_OK" if they succeded. But if i check that, using this constant, my compiler tells me that he does not know this identifier[/quote]
It's semantics, but don't confuse return type with return value. The return type is HRESULT. With regard to D3D_OK, be sure to check the documentation for the DirectX version you're using. D3D_OK is defined for Dx9. There are other return codes for other versions of DirectX.

i checked all the functions that LET me check them ( that do not have a void return type)[/quote]
Check the documentation for the function. Just because it returns void doesn't mean there's no indication for possible errors.

Any in particular that're giving you problems?
Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly. You don't forget how to play when you grow old; you grow old when you forget how to play.
Aardvajk
Aardvajk

HRESULT h=Whatever();

if(FAILED(h)) WeHaveAProblem();


D3D return codes use archane bitwise stuff. Be a cool kid and use FAILED() a lot.

Anyway, that being as it may, enable the DirectX debug mode from your DirectX control panel (it's in your start menu if you've installed the SDK) then absorb what it tells you.
Player089
Player089

Oh, yea. return type != return value, i actually knew that At least i hope i did ... Anyway, im using Dx11, so it's probably the wrong one. By saying "check the docu", do you mean the MSDN-docu or the actual docu-file comming with the SDK ?
However, i used the macro Aardvajk posted and it seems like those two functions failed ( CreateVertexShader and CreatePixelShader). However, im having a freaking hard time of getting the Error-Code in a MessageBox via GetLastError. MessageBox requires a string as 2nd argument, so i tried itoa(GetLastError(),buffer,10), but it told be something about the POSIX would not be right. Wow, im seriously failing atm... I'll better try this tomrrow, won't get any results in my current status




Buckeye
Buckeye
do you mean the MSDN-docu or the actual docu-file comming with the SDK ?[/quote]
If you have the latest SDK, the MSDN documentation and the SDK documentation should be the same.

With DirectX functions. you don't use GetLastError. You already have the error in the return code. Take a look at DXGetErrorDescription or DXGetErrorString.
Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly. You don't forget how to play when you grow old; you grow old when you forget how to play.
Player089
Player089
Ahhh okay, thanks for those two functions. I used them with those two functions who failed and the error message is : " E_INVALIDARG". Some arguement seems to be invalid ?
Buckeye
Buckeye

Ahhh okay, thanks for those two functions. I used them with those two functions who failed and the error message is : " E_INVALIDARG". Some arguement seems to be invalid ?

If you're coding things correctly, it sounds like it. You don't mention what you're checking or which functions in particular you're checking. If they're the CreateVertexShader calls, have you checked that CompileFromFile calls are successful?
Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly. You don't forget how to play when you grow old; you grow old when you forget how to play.
Player089
Player089
Yes. i checked them and they seem to work just fine. Doesnt make much sense that CreateVertexShader does not work, when CompileFromFile DID work. Weird.
Erik Rufelt
Erik Rufelt
Check your feature levels. If you compile for vs_5_0 for example, you need a feature level 11 device, while vs_4_0 requires 10.0, and for lower levels there's vs_4_0_level_9_1 and vs_4_0_level_9_3. If you create your device with the D3D11_CREATE_DEVICE_DEBUG flag and run your app with the debugger, you will see debug output that will most likely tell you why the shader couldn't be created.
ankhd
ankhd
get the books introduction to 3d game programming with directx 9.0c
a shaders approach by Frand d. Luna

and or the directx 10 book with the same name , he may even have dx 11 book now.
21st Century Moose
21st Century Moose

WHAT DOES THE FRICKING DEBUG RUNTIME SAY IF YOU ENABLE IT?

Sorry to shout, but get easily frustrated.


This. Switch on the debug runtime and run your program. Use the tools you have, they are there to help you solve problems like this.
Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls. 
Player089
Player089
Okay okay. I tried to do what you told be, but i actually failed.

I used the D3D11_CREATE_DEVICE_DEBUG flag with the D3D11CreateDeviceAndSwapChain() function, but using this flag makes the function-call fail. So i looked up what else i should do in order to make the function work with this flag, but i cannot see any folder named "DirectX Utilities" in my DirectX SDK-folder ( the tutorial i found wanted me to change something using the DirectX Control pannel, but there simply IS none in my SDK-folder). So, if i call the function with the DEBUG-flag, i get an error-code as return-value that means this : " Attempted to create a device with the debug layer enabled and the layer is not installed."
Erik Rufelt
Erik Rufelt
Uninstall any old SDK and download and re-install the newest: http://www.microsoft.com/downloads/en/details.aspx?displaylang=en&FamilyID=3021d52b-514e-41d3-ad02-438a3ba730ba
Then try again.

The control panel should be in "...\Microsoft DirectX SDK (June 2010)\Utilities\bin\x86\dxcpl.exe" or x64 for 64-bit. You shouldn't need it for D3D11 as you can use the flag when creating the device instead.

Maybe you need to make sure you're an administrator on the computer, but not sure about that...

And update your graphics drivers while you're at it, not just from Windows Update but directly from the Nvidia/AMD/Intel sites.
Player089
Player089
This is exactly the one i have installed and the exact same link where i downloaded it from. However, i'll download and install it again, because the "Ultility"-subfolder simply doesnt exist in my DirectX-SDK folder.
However, i was using DirectX11, so according to you, it should work without any further settings and by only using the DEBUG-Flag when creating the Device etc ? But it doesnt, hmm.


Im also currently downloading the latest drivers for my graphic card, thank you for that hint. But what's the use of it ?
Infinity95
Infinity95
The reason this doesn't work is because you are using HLSL Shader Model 5 but your graphics card most likely doesn't support it. Try using vs_4_0 and ps_4_0

Edit: Sorry for digging up this thread. Didn't see the date.
"Errare humanum est, sed in errare perseverare diabolicum."

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.