2016-03-30 7 views
1

OpenCLレイキャスターを作成しようとしています。したがって、私は何回もOpenGLテクスチャに描画しています。しかし、queue.enqueueNDRangeKernelは最終的に-9999を返します。私のカーネルコードからwrite_imagefを取り除くと、うまくいきます。そのため、問題が発生していると思いました。OpenCL - 描画するOpenGLテクスチャのクラッシュ

のOpenCLカーネル(分解)

__kernel void main(__write_only image2d_t screen) 
{ 
    unsigned int x = get_global_id(0); 
    unsigned int y = get_global_id(1); 

    int2 coords = (int2) (x, y); 
    write_imagef(screen, coords, (float4)(1,0,1,1)); 
} 

これはかつてのC++で実行されるコードです:

cl::Program::Sources sources; 
string code = ResourceLoader::loadFile(filename); 
sources.push_back({ code.c_str(),code.length() }); 

program = cl::Program(OpenCL::context, sources); 

if (program.build({ OpenCL::default_device }) != CL_SUCCESS) 
{ 
    cout << "Could not build program \"" << filename << "\"! Error:" << endl; 
    cout << "OpenCL: Error building: " << program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(OpenCL::default_device) << "\n"; 
    system("PAUSE"); 
    exit(1); 
} 
queue = CommandQueue(OpenCL::context, OpenCL::default_device); 
kernel = Kernel(program, "main"); 
//OpenGL texture 
ImageGL b(OpenCL::context, CL_MEM_READ_WRITE, GL_TEXTURE_2D, 0, argument, &error); 

if (error != 0) 
{ 
    cout << "CL Error: " << OpenCL::get_cl_error_string(error) << endl; 
    system("PAUSE"); 
    exit(error); 
} 
kernel.setArg(0, b); 

このコードはすべてのフレームを実行します:

何ができるか
glFinish(); 
queue.enqueueAcquireGLObjects(&this->buffersGL); 
NDRange range; 
if (lengthZ <= 0 && lengthY <= 0) 
    range = NDRange(lengthX); 
else if (lengthZ <= 0) 
    range = NDRange(lengthX, lengthY); 
else 
    range = NDRange(lengthX, lengthY, lengthZ); 

cl::Event wait; 

cl_int run_err = queue.enqueueNDRangeKernel(kernel, NDRange(), range, NullRange, NULL, &wait); 


if (run_err != 0) 
{ 
    cout << OpenCL::get_cl_error_string(run_err) << " (" << run_err << ")" << endl; 
    system("PAUSE"); 
} 
queue.enqueueReleaseGLObjects(&this->buffersGL); 

-9999エラーが発生し、どのように修正できますか?また、多くの場合、テクスチャに描画されていない "デッドピクセル"の大きな塊があります。

答えて

2

GLバッファの解放をエンキューしますが、完了するのを待ってはいけません。

queue.enqueueReleaseGLObjects(&this->buffersGL); 

(リークに注意!)このうち仕上がりイベントを取得、またはGLオブジェクトを解放するに進む前に、すべてのタスクを完了するために、コマンドキューで待機のいずれか。待ち行列の中の1つが別のものに依存するときは、自分で注文することになっています。

また、GLオブジェクトに依存する一連のタスクをキューに入れます。それらが完了するのを待つか(キューを終了する)、イベントを受け取り、エンキュー解放GLオブジェクトにフィードとして渡します。余談として

:少数のカーネルを使用して

は良いアイデア、代わりのピクセル当たり1かもしれません。

0

ピクセル単位ではなく、より少ないカーネルを使用することをお勧めします。

ありがとうございましたYakk!私は最初に単純に小さな画面サイズを使用してそれを試み、それは突然再び働いた!私が描いていたテクスチャが問題でしたが、それが判明しました。それは600×600ピクセルではなく、クラッシュの原因となっていました。どうやら、OpenCLはクラッシュする前に何度か「実際には存在しない」ピクセルに描画することができます。まだ奇妙な行動です...

関連する問題