cudaD3D9Begin makes application exit with code 1

Hey,

I’m working on a project (videodecoder) where i need to map parts of a program from the cpu to the gpu. I’ve managed to get a working kernel but atm it’s not optimised yet, as it copies the outcome of the last step back to host memory from where it’s send back to the device to show on the screen :D

Anyways, the code available was a cpp project and i tried to include extra parts but when i do CUDA_SAFE_CALL(cudaD3D9Begin(m_device)); I get The program ‘[1056] Application.exe: Native’ has exited with code 1 (0x1).

I can paste some code below . . from main.cpp

HRESULT InitD3D( HWND hWnd )

{

    // Create the D3D object, which is needed to create the D3DDevice.

    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) ) return E_FAIL;

	RECT m_rcWindowBounds;    

	RECT m_rcWindowClient; 

	GetWindowRect(hWnd,&m_rcWindowBounds);

	GetClientRect(hWnd,&m_rcWindowClient);

	int width	= m_rcWindowClient.right - m_rcWindowClient.left;

	int height	= m_rcWindowClient.bottom - m_rcWindowClient.top; 

  

	D3DPRESENT_PARAMETERS d3dpp; 

    ZeroMemory( &d3dpp, sizeof(d3dpp) );

	d3dpp.Windowed    	= TRUE;

    d3dpp.BackBufferCount  	= 1;

    d3dpp.SwapEffect    = D3DSWAPEFFECT_DISCARD;

    d3dpp.hDeviceWindow    = hWnd;

    d3dpp.BackBufferWidth  	= width;

    d3dpp.BackBufferHeight  	= height;

	d3dpp.BackBufferFormat  	= D3DFMT_A8R8G8B8;

    d3dpp.FullScreen_RefreshRateInHz= 0;

	d3dpp.PresentationInterval  = D3DPRESENT_INTERVAL_IMMEDIATE;

	UINT AdapterToUse    = D3DADAPTER_DEFAULT;

	D3DDEVTYPE DeviceType  	= D3DDEVTYPE_HAL;

	for (UINT Adapter = 0; Adapter < g_pD3D->GetAdapterCount(); Adapter++)

	{

  D3DADAPTER_IDENTIFIER9	id;

  HRESULT    	res;

 res = g_pD3D->GetAdapterIdentifier(Adapter,0,&id);

  

  if (strcmp(id.Description,"NVIDIA NVPerfHUD") == 0)

  {

  	AdapterToUse = Adapter;

  	DeviceType  = D3DDEVTYPE_REF;

  	break;

  }

	}

   if( FAILED( g_pD3D->CreateDevice( AdapterToUse, DeviceType, hWnd,

                                      D3DCREATE_HARDWARE_VERTEXPROCESSING,

                                      &d3dpp, &g_pd3dDevice ) ) )

    {

  if( FAILED( g_pD3D->CreateDevice( AdapterToUse, DeviceType, hWnd,

                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,

                                      &d3dpp, &g_pd3dDevice ) ) )

  {

  	return E_FAIL;

  }

    }

	D3DCAPS9 caps;

	int dynamicTexture = 0;

	g_pD3D->GetDeviceCaps(AdapterToUse,DeviceType,&caps);

	dynamicTexture = (caps.Caps2 | D3DCAPS2_DYNAMICTEXTURES);

   

	g_viewImage  	= NULL;

	g_videoDecoder->profile = g_profile;

	g_displayController  = new     CDisplayController(width,height,g_pd3dDevice,hWnd,g_videoDecoder->getVideoMemory(),g_state);

Now i enter CDisplayController class…

{

	m_GPUstate   = GPUstate;

	m_width    = width;

	m_height   = height;

	m_widthUV   = width / 2;

	m_heightUV   = height / 2;

  HRESULT hr;

  m_device  = device;

  m_device->CreateTexture(width,height,1,D3DUSAGE_RENDERTARGET,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&m_renderTexture,NULL);

  m_renderTexture->GetSurfaceLevel(0,&m_renderSurface);	

  	

  m_viewport.X     = 0;

  m_viewport.Y     = 0;

  m_viewport.Width = width;

  m_viewport.Height= height;

  m_viewport.MinZ  = 0.0f;

  m_viewport.MaxZ  = 10.0f;

  m_hwnd    = hwnd;

  	VOID* pData;

  	float m_w2	= (float)width / 2;

  	float m_h2	= (float)height / 2;

  	CUDAD3DVERTEXTEXTURE aQuad[] =  {	{ -m_w2, m_h2, 0.0f, 0.0f, 0.0f},

          	{ -m_w2,-m_h2, 0.0f, 0.0f, 1.0f},

          	{  m_w2, m_h2, 0.0f, 1.0f, 0.0f},

          	{  m_w2,-m_h2, 0.0f, 1.0f, 1.0f}

          };

  	m_device->CreateVertexBuffer(sizeof(aQuad),D3DUSAGE_WRITEONLY,VIEWIMAGEFVF,D3DPOOL_MANAGED,&m_imageVB,NULL);

  	m_imageVB->Lock(0,sizeof(pData),(void**)&pData,0);

  	memcpy(pData,aQuad,sizeof(aQuad));

  	m_imageVB->Unlock();

  	D3DXMatrixOrthoRH(&m_projection,(float)m_width,(float)m_height,0,10);

  	D3DXMatrixIdentity(&m_modelview);

  	device->GetRenderTarget(0,&m_backBuffer);

  	m_renderTexture = NULL;  

  	m_imageVB  = NULL;

  	m_videoMemory	= videoMemory;

  	m_videoMemoryGPU= (CVideoMemoryGPU*)videoMemory;

  	initCUDA(m_device);

initCUDA is defined in a seperate cu file (so called via extern “C” void…)

and m_device is g_pd3dDevice from the main

extern "C" void initCUDA(LPDIRECT3DDEVICE9 m_device)

{

	CUT_DEVICE_INIT();

	CUDA_SAFE_CALL(cudaD3D9Begin(m_device));

}

At that last line the application exits with code 1 … (Using breakpoints in visual studio, it doesn’t go further. .

Sorry for pasting a lot of code , any help would be appreciated …

EDIT: styling and typo

Only a few hours further and I think I am going towards a solution . .

After searching and searching I accidently tried to re-run the SimpleD3D example project which was included, and that one gave an unexcepted error and one line of code being

           CUDA_SAFE_CALL(cudaD3D9Begin(g_pd3dDevice));

When I rebooted my system, the example project runs fine again (and I can start it over and over again…)

What I am thinking now is that cudaD3DEnd() isn’t executed correctly in my own project… causing other instances of cudaD3D9Begin() to fail, no matter which application/project.

Anybody can confirm this theory?

Well put some big printf’s around your cudaD3DEnd and print the return value of the call too?

It works now,
I believe it’s very weird though that the whole system needs to be rebooted in case somebody forgot to call cudaD3Dend()…
Which in my case only was called 50% of cases . . (if statements, and not called in the else . . :P)

Oke, continuing, next step i tried to register the buffer . . (which i gave as argument to initCUDA

which became

extern "C" void initCUDA(LPDIRECT3DDEVICE9 device, LPDIRECT3DVERTEXBUFFER9	m_imageVB)

{

	CUT_DEVICE_INIT();

	CUDA_SAFE_CALL(cudaD3D9Begin(m_device));

	CUDA_SAFE_CALL(cudaD3D9RegisterVertexBuffer(m_imageVB));

}

I didn’t change at any other place . . but it fails at the bottom line with “has exited with code 1”

Is there a way to program/debug faster, because since the program exited there, it didn’t call cudaD3D9end(), so I have to reboot everytime :D before i can continue…

Thanks and best regards

Well, if you look at what the CUDA_SAFE_CALL macro does, you can just make your own version of the macro to call cudaD3D9end before exiting.

If i remove the macro, the program keeps running fine :D, but I don’t use the vertexbuffer yet:p
I found it’s located in cutil i guess
But is there a way to find more information on why the registervertexbuffer fails?

Print the error-value. I think that is normally done with CUDA_SAFE_CALL, or otherwise a CUT_CHECK_ERROR afterwards can be useful. And it is indeed defined in cutil.h

Trying that now, nobody familiar enough with direct3d to get the fault out of my code?

I am so stupid, right before i called initCUDA the pointer was set to NULL…
Anyways, I still didn’t get how to create a custom macro that calls cudaD3D9end(), neither did i get any more debug information on why this CUDA_SAFE_CALL fails…
Adding cudaD3D9end() in the cutil.h, is no good use, since i would have to include d3d9 interoper.
I notice that errors are print to a file, but I can’t seem to find which file it goes cuz this error only happens at runtime, not during compiling…

KR
Niels

Put this in the beginning of your header or cu file :

#  define CUDA_SAFE_CALL_NO_SYNC_D3D( call) do {                                 \

    cudaError err = call;                                                    \

    if( cudaSuccess != err) {                                                \

        fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n",        \

                __FILE__, __LINE__, cudaGetErrorString( err) );              \

        cudaD3D9end() \

        exit(EXIT_FAILURE);                                                  \

    } } while (0)

#  define CUDA_SAFE_CALL_D3D( call) do {                                         \

    CUDA_SAFE_CALL_NO_SYNC_D3D(call);                                            \

    cudaError err = cudaThreadSynchronize();                                 \

    if( cudaSuccess != err) {                                                \

        fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n",        \

                __FILE__, __LINE__, cudaGetErrorString( err) );              \

        cudaD3D9end() \

        exit(EXIT_FAILURE);                                                  \

    } } while (0)

And change you CUDA_SAFE_CALL calls to CUDA_SAFE_CALL_D3D.

You could also have just put it in cutil.h, since these are macros, no needs for including. Errors are printed to stderr, which is the standard error output (don’t know what that is on windows). Oh btw. I think that these macros are the same on Linux and Windows, but you have to check.

Excuses, it compiles! Had to change the 2 typos cudaD3D9end() => cudaD3D9End()

Will try to use it now. .

I also have the same problem. I tried the solution you have discussed, but it does not work. :no: Does it work on your computer? Thanks,