Lock fails when device lost

Started by
4 comments, last by dietepiet 15 years, 9 months ago
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?
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?
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.
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?
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.

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

This topic is closed to new replies.

Advertisement