Sign in to follow this  
agisler

access violation reading location

Recommended Posts

Hi,

All of a sudden I have been getting an error at my EndScene and Present. I have spent the last day trying to figure this out but have had no luck. The project builds with no errors but when I run it I get an error "Unhandled exception at 0x011b1a4f in Ping.exe: 0xC0000005: Access violation reading location 0x00000000".

The error happens on the EndScene.

void CDirectx::EndFrame()
{

g_p3DDevice->EndScene();
g_p3DDevice->Present(NULL,NULL,NULL,NULL);
}


The only thing I have changed recently is I have added another class. I have commented the class out so as far as I know thats not the problem.


Many Thanks

Share this post


Link to post
Share on other sites
Thanks again Evil Steve!! Its great how you can spot the problem but if its staring me in the face I am blind as a bat. :)

The problem was in where I created my device.



if (FAILED( g_p3DObject->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_REF,
c_pPlatform->GetMainWindow()->GetHandle(),
vertexProcessing,
&d3dParam,
&g_p3DDevice)))



The problem was that I was using D3DDEVTYPE_HAL instead of D3DDEVTYPE_REF like above.

I looked up the differences and from what I read D3DDEVTYPE_REF should only be used for development purposes. So why might I be getting errors with hal? I rather fix these things now than face bigger problems in the future.

Many thanks once again.

Share this post


Link to post
Share on other sites
What do the Debug Runtimes say? If CreateDevice() fails with HAL but succeeds with REF, it's usually because you're trying to use a feature that your card doesn't support. You should be checking the device caps for everything you need, so you know if a function is likely to fail. You should also be able to gracefully handle "major" functions like CreateDevice() failing, and abort the program and display an error the the user.

The REF device is a software renderer, that's designed to be a "perfect" GPU / driver - it'll implement everything possible, but it'll be extremely slow. The only time you should be using it is if you're checking up on a potential driver bug (If the results from a HAL and REF device differ, REF is always right), or if you're trying to develop a feature that your graphics card doesn't support (E.g. if you needed to use pixel shaders but your dev PC only had a GeForce 2)

Share this post


Link to post
Share on other sites
Thanks for the advice. I am going to spend a lot of time doing checking the device caps.

My debug runtime says:

D3D9 Helper: IDirect3D9::CreateDevice failed: D3DERR_NOTAVAILABLE

Isn't my D3DERR a library file or dll file?

How come my return is not being called when the device does fail?


if (FAILED( g_p3DObject->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_REF,
c_pPlatform->GetMainWindow()->GetHandle(),
vertexProcessing,
&d3dParam,
&g_p3DDevice)))
{
return;
}



Thanks for the explanation on HAL and REF. That all makes a lot of sense now.


Many Thanks

agisler

Share this post


Link to post
Share on other sites
Quote:
MSDN Docs
D3DERR_NOTAVAILABLE
This device does not support the queried technique.


I did once have a laptop that didn't support hardware vertex processing but that is a bit unlikely.

Could you post your D3DPRESENT_PARAMS set up? It's probable that you are requesting something in there that the hardware doesn't support.

You'll also find it easier to track this stuff if you actually respond to a positive from the FAILED() macro with an error message rather than just ignoring the result.

Share this post


Link to post
Share on other sites
In addition to what Aardvajk said; make sure your debug output level in the DirectX Control Panel is set to maximum - you should get more information than that, telling you exactly what is unavailable. Can you paste your entire debug output?

Share this post


Link to post
Share on other sites
Hi,

Sorry about taking so long to get back. This is what was in my debug window....

'Ping.exe': Loaded 'C:\CODEBASE\ANDREW_GISLER\Ping\Debug\Ping.exe', Symbols loaded.
'Ping.exe': Loaded 'C:\Windows\System32\ntdll.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\kernel32.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\KernelBase.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\d3d9.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\msvcrt.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\sechost.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\rpcrt4.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\user32.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\gdi32.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\lpk.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\usp10.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\version.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\d3d8thk.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\dwmapi.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\msvcr100d.dll', Symbols loaded.
'Ping.exe': Loaded 'C:\Windows\System32\imm32.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\msctf.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\avgrsstx.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\advapi32.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\uxtheme.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\ole32.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\cryptbase.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\clbcatq.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\oleaut32.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\d3d9d.dll', Cannot find or open the PDB file
'Ping.exe': Loaded 'C:\Windows\System32\winmm.dll', Cannot find or open the PDB file
Direct3D9: :====> ENTER: DLLMAIN(6820d9a0): Process Attach: 000009fc, tid=00000ff0
Direct3D9: :====> EXIT: DLLMAIN(6820d9a0): Process Attach: 000009fc
Direct3D9: (INFO) :Direct3D9 Debug Runtime selected.
'Ping.exe': Loaded 'C:\Windows\System32\nvd3dum.dll', Cannot find or open the PDB file
D3D9 Helper: IDirect3D9::CreateDevice failed: D3DERR_NOTAVAILABLE
First-chance exception at 0x009e1a9f in Ping.exe: 0xC0000005: Access violation reading location 0x00000000.
Unhandled exception at 0x009e1a9f in Ping.exe: 0xC0000005: Access violation reading location 0x00000000.


Here is my code for initialising my parameters and etc.

g_p3DObject = Direct3DCreate9(D3D_SDK_VERSION);
if (!g_p3DObject)
{

}
m_iWidth=c_pPlatform->GetMainWindow()->m_iWidth;
m_iHeight=c_pPlatform->GetMainWindow()->m_iHeight;

g_p3DObject->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &g_displayMode);

D3DCAPS9 D3DCaps;

g_p3DObject->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &D3DCaps );
DWORD vertexProcessing = 0;
if ( D3DCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
{

vertexProcessing = D3DCREATE_HARDWARE_VERTEXPROCESSING;
// Check for pure device
if ( D3DCaps.DevCaps & D3DDEVCAPS_PUREDEVICE )
{
vertexProcessing |= D3DCREATE_PUREDEVICE;
}

}
else
{

vertexProcessing = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
}

D3DPRESENT_PARAMETERS d3dParam;
ZeroMemory (&d3dParam, sizeof (d3dParam));
d3dParam.Windowed =true;
d3dParam.AutoDepthStencilFormat = D3DFMT_D24FS8;
d3dParam.EnableAutoDepthStencil=TRUE;
d3dParam.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dParam.BackBufferFormat=D3DFMT_X8R8G8B8;
d3dParam.BackBufferCount=1;
d3dParam.BackBufferHeight=m_iHeight;
d3dParam.BackBufferWidth=m_iWidth;
d3dParam.hDeviceWindow= c_pPlatform->GetMainWindow()->GetHandle();



Quote:

You'll also find it easier to track this stuff if you actually respond to a positive from the FAILED() macro with an error message rather than just ignoring the result.

If i understand this correctly your saying that I should do something other than just simply using the return keyword? I was planning on putting something there more significant at a later time. Its just there for temporary purposes.

Thanks again for all the help.

Share this post


Link to post
Share on other sites
It is most likely that your hw/device doesn't support D24FS8 depth stencil format.
you should check (among many things) it before feeding it into pparams:


HRESULT hr;
hr = g_p3DDevice->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
g_displayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24FS8);
if(FAILED(hr))
{
MessageBox(0, "ERROR: D3DFMT_D24FS8 unavilable", 0, 0);
DebugBreak();
return;
}


Share this post


Link to post
Share on other sites
and also you definitely shouldn't do this

m_iWidth=c_pPlatform->GetMainWindow()->m_iWidth;
m_iHeight=c_pPlatform->GetMainWindow()->m_iHeight;

the window can be any size, while there are certain available resolutions for device. Set back buffer sizes to what ...
g_p3DObject->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &g_displayMode);...
tells you, or set them to 0 if you run in windowed mode.

Share this post


Link to post
Share on other sites
Quote:
Original post by JohnnyCode
the window can be any size, while there are certain available resolutions for device. Set back buffer sizes to what ...


Actually, in windowed mode you can have any sized back buffer regardless of the display modes that the device supports.

Share this post


Link to post
Share on other sites
1. As belfegor said, your card probably doesn't support D3DFMT_D24FS8 - the card caps spreadsheet that comes with the SDK shows that only a few ATI cards support that format.
You should be calling IDirect3D9::CheckDeviceFormat to see if a format is supported, and then IDirect3D9::CheckDepthStencilMatch to check that the depth buffer format can be used with the backbuffer format you've chosen.
I wrote a tutorial about this stuff, some of that might be useful.

2. Oddly, the debug runtimes don't tell you what's unsupported - usually they'll give a much more descriptive error than that...

3. I hope that GetMainWindow()->m_iWidth gives you the size of the client area, and not the sizes you passed to CreateWindow :P. You should be using AdjustWindowRect (See the tutotial code I linked above) to convert window size to client size, so your backbuffer and client area are the same size.

Share this post


Link to post
Share on other sites
Ok, WOW is all I can say!! You all have given me a lot to work on and its great!!

Thank you Evil Steve for the link of those tutorials you created. There some of the best I have read online and in books. A few questions though.

Currently I am using CreateWindowEx, is there any reason why I should not use this and should use CreateWindow()?

I fixed the problem of setting the client window height and width to be the same as the buffers.

This is where I define the window and register it.

void CPlatform::Initialise(char* cAppName, int iXPos, int iYPos, int iWidth, int iHeight, int argc, char** argv)
{
// Define the window
memset(&wStructure,0,sizeof(wStructure)); //set the size of the window structure to 0
wStructure.cbSize = sizeof( wStructure ); //initialize the count byte size of the window structure
wStructure.style = CS_HREDRAW | CS_VREDRAW; //redraw when the window height or width changes
wStructure.lpfnWndProc = WindowsProcedure;
wStructure.cbClsExtra = 0;
wStructure.cbWndExtra = 0;
wStructure.hInstance = hInstance;
wStructure.hIcon = NULL;
wStructure.hCursor = NULL;
wStructure.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
// wStructure.lpszMenuName = NULL;
wStructure.lpszClassName = cAppName;
// wStructure.hIconSm = LoadIcon( hInstance, IDI_APPLICATION );


// Register the window
if (!RegisterClassEx( &wStructure ))
{
CLogger::Write("window register failed");
}
else
c_pMainWindow= new CWindow(cAppName,iXPos,iYPos,iWidth,iHeight,hInstance);
}



This is where I adjustwindow size and create the window
[source =lang"cpp"]
CWindow::CWindow(char *cAppName, int iXPos, int iYPos, int iWidth, int iHeight,HINSTANCE hInstance)
{

m_iWidth = iWidth;
m_iHeight = iHeight;

/*
next i will use AdjustWindowRect to determine the window size based on the client area size;
*/

dwStyle = (WS_OVERLAPPEDWINDOW| WS_VISIBLE) & ~WS_THICKFRAME;
rc.top=rc.left=0;
rc.right = m_iWidth;
rc.bottom= m_iHeight;
AdjustWindowRect(&rc, dwStyle, FALSE);
sizeWindow.cx=rc.right - rc.left;
sizeWindow.cy=rc.bottom - rc.top;

m_windowHandle = CreateWindowEx(dwStyle, cAppName, cAppName, dwStyle, iXPos, iYPos, sizeWindow.cx,sizeWindow.cy, NULL, NULL, hInstance, this);

}



At the moment my window will not show up. It just sits in the taskbar but when i try to view it nothing happens.

I have done all the D3DFORMAT checks now along with the device cap checks. This was from following the tutorials.Here is my Directx initialization:


bool CDirectx::Initialise(CPlatform * c_pPlatform)
{
//get direct3d pointer
g_p3DObject = Direct3DCreate9(D3D_SDK_VERSION);
//check if pointer was successful
if (!g_p3DObject)
{
CLogger::Write("could not get direct3d pointer");
return false;
}
//get current desktop format
hResult=g_p3DObject->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &g_displayMode);
if(FAILED(hResult))
{
CLogger::Write("get adapter display mode failed");
g_p3DObject->Release();
g_p3DObject=NULL;
return false;
}
fmtBackBuffer=g_displayMode.Format;

//Check to see what depth buffer supports
D3DFORMAT fmtDepths[] = { D3DFMT_D32,
D3DFMT_D24X8,
D3DFMT_D24S8,
D3DFMT_D24X4S4,
D3DFMT_D16,
D3DFMT_D15S1};
D3DFORMAT fmtDepthSelected = D3DFMT_UNKNOWN;
size_t nDepthFormats = sizeof(fmtDepths) / sizeof(fmtDepths[0]);
for (size_t i=0; i<nDepthFormats; ++i)
{
//see if we support the format
hResult= g_p3DObject->CheckDeviceFormat (D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
g_displayMode.Format,
D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE,
fmtDepths[i]);
if(FAILED(hResult))
{
//graphics card does not support this format
continue;
}
//check if this format can be used with backbuffer format
hResult = g_p3DObject->CheckDepthStencilMatch(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
g_displayMode.Format,fmtBackBuffer,fmtDepths[i]);
if(FAILED(hResult))
{
//graphics card does not support this z-buffer
continue;
}
//this format is usable
fmtDepthSelected=fmtDepths[i];
break;

}

if(fmtDepthSelected==D3DFMT_UNKNOWN)
{
return false;
}

D3DCAPS9 D3DCaps;

g_p3DObject->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &D3DCaps );
DWORD vertexProcessing = 0;
if ( D3DCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
{

vertexProcessing = D3DCREATE_HARDWARE_VERTEXPROCESSING;
// Check for pure device
if ( D3DCaps.DevCaps & D3DDEVCAPS_PUREDEVICE )
{
vertexProcessing |= D3DCREATE_PUREDEVICE;
}

}
else
{

vertexProcessing = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
}


m_iWidth=c_pPlatform->GetMainWindow()->m_iWidth;
m_iHeight=c_pPlatform->GetMainWindow()->m_iHeight;

D3DPRESENT_PARAMETERS d3dParam;
ZeroMemory (&d3dParam, sizeof (d3dParam));
d3dParam.Windowed =true;
d3dParam.EnableAutoDepthStencil=TRUE;
d3dParam.AutoDepthStencilFormat = fmtDepthSelected;
d3dParam.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dParam.BackBufferHeight=c_pPlatform->GetMainWindow()->sizeWindow.cy;
d3dParam.BackBufferWidth=c_pPlatform->GetMainWindow()->sizeWindow.cx;
d3dParam.BackBufferFormat=D3DFMT_X8R8G8B8;
d3dParam.BackBufferCount=1;

d3dParam.hDeviceWindow= c_pPlatform->GetMainWindow()->GetHandle();

if (FAILED( g_p3DObject->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
c_pPlatform->GetMainWindow()->GetHandle(),
vertexProcessing,
&d3dParam,
&g_p3DDevice)))
{
return false;
}
return true;
}




I am not sure why my debugger is not ouputing more information. I checked it more than once to make sure the debug output level was to the max along with the other settings.

Thanks again to everyone that has been helping me work through this.

Share this post


Link to post
Share on other sites
Quote:
Original post by agisler
Ok, WOW is all I can say!! You all have given me a lot to work on and its great!!

Thank you Evil Steve for the link of those tutorials you created. There some of the best I have read online and in books.
Thanks! [smile]

Quote:
Original post by agisler
Currently I am using CreateWindowEx, is there any reason why I should not use this and should use CreateWindow()?
Not really - CreateWindow is actually a macro that just calls CreateWindowEx with 0 as the first parameter. If you're not using the extended window styles, it doesn't make any difference at all.

Quote:
Original post by agisler
At the moment my window will not show up. It just sits in the taskbar but when i try to view it nothing happens.
The first parameter to CreateWindowEx is the extended style, you should pass 0 for that (Your current style flags probably map to some totally unrelated extended flags).

Quote:
Original post by agisler
I am not sure why my debugger is not ouputing more information. I checked it more than once to make sure the debug output level was to the max along with the other settings.
It looks like the output you get is normal - I tried it myself and that's the only output I get too. The debug runtimes are usually more helpful than that, it seems that this is all the output they give for unsupported formats unfortunately.

Share this post


Link to post
Share on other sites
That did the trick!!

Everything seems like its running great now. I think my next step is to work on getting the window fullscreen and checking for lost device.

Thank you all so much!!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this