Jump to content
  • Advertisement
Sign in to follow this  
dietepiet

Lock fails when device lost

This topic is 3622 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, Does anyone know of situations that would cause IB::Lock to return success but set the data pointer to invalid memory? This happens consistently for me when the device is lost and a index buffer is locked with D3DLOCK_NOOVERWRITE. The buffer is a dynamic write only buffer and both Lock and Unlock return D3D_OK. When the first byte is written I get an access violation. My current fix for this is to call TestCooperativeLevel prior to every lock call. The D3D documentation specifically states that I should not have to do this. This is definitely not correct behavior, has any one had this problem and is it mu fault?

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by dietepiet
Hello,

Does anyone know of situations that would cause IB::Lock to return success but set the data pointer to invalid memory? This happens consistently for me when the device is lost and a index buffer is locked with D3DLOCK_NOOVERWRITE. The buffer is a dynamic write only buffer and both Lock and Unlock return D3D_OK. When the first byte is written I get an access violation. My current fix for this is to call TestCooperativeLevel prior to every lock call. The D3D documentation specifically states that I should not have to do this.

This is definitely not correct behavior, has any one had this problem and is it mu fault?
Does it work when the device is not lost? This sounds like a driver bug to me - do you have the latest drivers?

Share this post


Link to post
Share on other sites
Thnx for your replay.

I'v made the smallest possible program giving the error:



unsigned int num_indices = 12;

// setup DirectX device

LPDIRECT3D9 g_pD3D;
LPDIRECT3DDEVICE9 g_pd3dDevice;

if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
throw( "Direct3DCreate9 failed" );

D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(D3DPRESENT_PARAMETERS) );

HWND hWnd = (HWND)Window;

d3dpp.Windowed = FALSE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.hDeviceWindow = hWnd;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;

d3dpp.BackBufferWidth = 800;
d3dpp.BackBufferHeight = 600;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferCount = 1;

if( FAILED( g_pD3D->CreateDevice( 0 , D3DDEVTYPE_HAL, hWnd ,
D3DCREATE_HARDWARE_VERTEXPROCESSING ,
&d3dpp, &g_pd3dDevice ) ) )
ERROR( "CreateDevice failed" );

// setup index buffer

LPDIRECT3DINDEXBUFFER9 indexBuffer;

if( g_pd3dDevice->CreateIndexBuffer(
num_indices * 4 , // Length
D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, // Usage
D3DFMT_INDEX32, // Format
D3DPOOL_DEFAULT, // Pool
&indexBuffer, // ppIndexBuffer
NULL // pSharedHandle
) != D3D_OK )
{
return -1;
}

unsigned int inBuffer = 0;

// render loop

bool done = false;
do
{
// handle windows messages
MSG msg;
if(PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
DispatchMessage (&msg) ;
if( msg.message == WM_QUIT )
done = true;
}
else
{
// render scene
g_pd3dDevice->BeginScene();
g_pd3dDevice->Clear( 0,
NULL,
D3DCLEAR_TARGET ,
0xFF00FF00 ,
1.0f,
0 );

/*
Lock the next 3 free indices in the buffer with D3DLOCK_NOOVERWRITE
If the buffer is full, discard the whole buffer and start over
*/


DWORD lockFlags = D3DLOCK_NOOVERWRITE;
if( inBuffer == num_indices )
{
inBuffer = 0;
lockFlags = D3DLOCK_DISCARD;
}

unsigned int *index;
HRESULT hr = indexBuffer->Lock(
inBuffer * 4 ,
3 * 4 ,
(void**)(&index) ,
lockFlags );

// check the output
if( hr != 0 || index == 0 )
return -2;

// write the indices
*(index++) = 0; *(index++) = 1; *(index++) = 2;

indexBuffer->Unlock();

// three indices are used
inBuffer += 3;

g_pd3dDevice->EndScene();
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
} while(!done);

// release everything
indexBuffer->Release();

SAFE_RELEASE( g_pd3dDevice );
SAFE_RELEASE( g_pD3D );




It runs fine, until a press alt-tab. Then it immidiately crashes when writing the indices with a memory violation. So it failles while the driver is lost. According to the DX specifications, it shouldn't be a problem.

I can't see whats wring with this code. I will try to download a more recent driver. But as this is a common trick for sprite rendering, if it where a driver bug many more applications should probably crash.

Share this post


Link to post
Share on other sites
Nope, installing the latest driver does not help.
I also tried virtually the same code, but than with DirectX 8 which works fine.
I came on this idea because I saw that in the DirectX 8 pointsprite sample, they use exactly the same locking schema. So either they changed something from 8 to 9, or I don't get it.

Anyone any ideas or had the same problem?

Share this post


Link to post
Share on other sites
Did you try running it with the reference rasterizer? I'm at work right now so I can't test it out, but when I get home I'll try running your program to see what results I get.

Share this post


Link to post
Share on other sites
Why didn't i think of that :) In reference mode, it works like a charm. Also, i tried one other graphic device which worked fine as well. This may indicate either a bug in my device driver or something that is actually not allowed in DX9 (although allowed in DX8) but works with most drivers anyway.

Probably just my driver...

Thanks for your help

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!