2016-04-24 18 views
2

私はOpenGL interopでOpenCLを使用しようとしています。 GPU上のパストレースアルゴリズムを計算し、GLテクスチャを四角に描画します。 Intel CPU上で動作するように動作しますが、GTX 970で動作させようとすると、GLテクスチャのロックを解除する際にsegfaultが発生します。それが原因か実行中のカーネルであればDunno。私はコードがそれ自体のために話すようにします。私はOpenCL C++ラッパーbtwを使用しています。OpenCL/OpenGL相互運用性テクスチャsegfault

GLテクスチャの作成

glGenTextures(1, &texture); 
glBindTexture(GL_TEXTURE_2D, texture); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer); 
glBindTexture(GL_TEXTURE_2D, 0); //Unbind texture 

CLテクスチャの割り当て

m_textureCL = cl::ImageGL(m_context, 
     CL_MEM_READ_WRITE, 
     GL_TEXTURE_2D, 
     0, 
     texture, 
     &errCode); 

RunKernel機能

//----------------------------------------------------------------------------- 
// Lock texture 
//----------------------------------------------------------------------------- 
std::vector<cl::Memory> glObjects; //Create vector of GL objects to lock 
glObjects.push_back(m_textureCL); //Add created CL texture buffer 
glFlush(); //Flush GL queue 

errCode = m_cmdQueue.enqueueAcquireGLObjects(&glObjects, NULL, NULL); 
if(errCode != CL_SUCCESS) { 
    std::cerr << "Error locking texture" << errCode << std::endl; 
    return errCode; 
} 
//----------------------------------------------------------------------------- 

//----------------------------------------------------------------------------- 
// Run queue 
//----------------------------------------------------------------------------- 
errCode = m_cmdQueue.enqueueNDRangeKernel(
     m_kernel, 
     cl::NullRange, 
     cl::NDRange(height*width), 
     cl::NullRange, 
     NULL, 
     NULL); 
if(errCode != CL_SUCCESS) { 
    std::cerr << "Error running queue: " << errCode << std::endl; 
    return errCode; 
} 
//--------------------------------------- 


//----------------------------------------------------------------------------- 
// Unlock 
//----------------------------------------------------------------------------- 
errCode = m_cmdQueue.enqueueReleaseGLObjects(&glObjects, NULL, NULL); 
if(errCode != CL_SUCCESS) { 
    std::cerr << "Error unlocking texture: " << errCode << std::endl; 
    return errCode; 
} <<------ Here's where segfault occurs, can't get past this point 

カーネル関数のデフ。

カーネルでテクスチャへの書き込み
__kernel void RadianceGPU (
    __write_only image2d_t texture, 
    other_stuff...) 

write_imagef(
     texture, 
     (int2)(x, height-y-1), 
     (float4)(
      clamp(framebuffer[id].x, 0.0f, 1.0f), 
      clamp(framebuffer[id].y, 0.0f, 1.0f), 
      clamp(framebuffer[id].z, 0.0f, 1.0f), 
      1.0f) * 1.0f); 

興味深いwrite_imagefは()UNSIGNED_BYTEされたテクスチャにもかかわらず動作することです。

編集: 最後に、問題の原因を突き止めました。 CLプロパティの作成中に間違った表示を設定していました。私はGLFWのウィンドウをペーストしました。これはNVIDIAドライバに問題を引き起こします。 glxGetCurrentDisplayまたはglfwGetX11Displayを使用する必要があります。これにより、segfaultが修正されます。

+0

のOpenCLのどのバージョンを使用していますか? – Andreas

+0

Nvidia CUDA 1.2 – Nixx

答えて

2

これはあなたの問題だとは思っていませんが、とにかくそれを打ち明けます。

glObjectへのアクセスを移植可能な方法で同期化していません。 OpenCLの1.1から:

前clEnqueueAcquireGLObjectsを呼び出すには、アプリケーションが mem_objectsで指定されたオブジェクトにアクセス 保留中のGL操作が完了していることを確認する必要があります。これは、glFinishコマンド の発行を完了し、これらのオブジェクトへの保留中の参照を含むすべてのGLコンテキスト上で実行することによって、移植可能に達成することができます( )。 実装は、より効率的な同期方法を提供するかもしれません。 いくつかのプラットフォームでglFlushを呼び出す例で十分でしょう。 同期がスレッド内で暗黙的に行われる場合があります。 ベンダー - GLコマンドストリームにフェンスを配置し、そのフェンスの完了を待つ固有の拡張子CLコマンド キュー。 glFinish以外の同期方法は、現時点でOpenGL実装間で移植可能な ではないことに注意してください。

基本的には、移植可能な動作にはglFinishが必要です。

同様に、clEnqueueReleaseGLObjectsを呼び出した後、アプリケーション がオブジェクトにアクセス その保留中のOpenCLの操作を確実にする責任がある:すでに関心があるかもしれないより多くの情報がある引用された以下の段落で

これらのオブジェクトを参照する後続のGLコマンドを実行する前に、mem_objectsで指定されたオブジェクトが で完了しました。これは、clEnqueueRelease GL clWaitForEventsをclEnqueueRelease GL オブジェクトによって返されたイベントオブジェクトで呼び出すか、clFinishを呼び出すことによって移植可能に実行できます。上記のように、いくつかの実装 がより効率的なメソッドを提供するかもしれません。ここで

から引用した文書へのリンクです:https://www.khronos.org/registry/cl/specs/opencl-1.1.pdf#nameddest=section-9.8.6

+0

あなたの答えをありがとう、私はチャンスを得ると、私はそれを撃つだろう。私が気にする別のことは、私がGLテクスチャにアクセスすることができないCLテクスチャを割り当てるときです。これはNvidia opencl 1.2とOpenGL 4.5を使用しているときに起こりますが、Intel CPU/GPUとOpenGL 3.3でopencl 1.2を使用しているときには何の問題もありません。 – Nixx

+0

@Nixx Postこれはもう一つの質問コードです。 – Andreas