4

問題:フレームバッファにバインドされたRenderbuffer(またはTexture)を共有しようとすると、clSetKernelArg()が呼び出されたときに失敗します。徹底的なエラーチェックでは、その呼び出しまで問題は報告されません。

私のプログラムは、60fps(16.7msフレーム)で動作するビデオプロジェクターのフレームを生成します。

私のカーネルは(通常)24msで実行されますが、各フレーム間で50msかかります。余分なコストの一部は、GPUを使用してピクセルを計算し、次に読み取りバッファーを使用してデータGPUからプルし、glDrawPixelsを使用してGPUに戻して表示するためだと思います。OpenGL / OpenCLの相互運用を試して、2つの余分なコピー操作を回避するのに最適な状況です。

多くの例があり、 OpenCLとVBOを共有することに成功し、それに書き込むことができますが、それは私を助けません。頂点データは書きたくありません。計算された2D画像だけを書きます。

これを行うには2つの異なる方法の例があり、どちらもフレームバッファオブジェクトを含みます。

RenderbufferをFramebufferにアタッチするか、TextureをFramebufferにアタッチすることができます。

次に、openclでそのバッファーに書き込み、openglで表示できるようになります。余分なコピーはありません。

私はコードでこれのいくつかの例を見つけました、そして私は例がそれをするように言うのとまったく同じようにすべてをしていると思います、しかし多分それはOSXで壊れていますか?..動作しないため。clSetKernelArgを実行しようとするまで、FBOは「完了」であり、途中でエラーは発生しません。その呼び出しはエラー-38、CL_INVALID_MEM_OBJECTを返します。

*注:表示したい2D RGB画像を作成するだけなので、テクスチャよりもRenderbufferを使用したいと思います。しかし、私は必死になってテクスチャを試しました。それでも助けにはなりません。

私はこれらのステップをこの順序で、間に他のいくつかのものを入れて行います:

kCGLContext = CGLGetCurrentContext(); 
kCGLShareGroup = CGLGetShareGroup( kCGLContext );

glGenFramebuffers( 1, &fboid );
glBindFramebuffer( GL_FRAMEBUFFER, fboid );

glGenRenderbuffers( 1, &rboid );
glBindRenderbuffer( GL_RENDERBUFFER, rboid );
glRenderbufferStorage( GL_RENDERBUFFER, GL_RGBA, rb_wid, rb_hgt );

glboid = rboid;

glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboid );

それから:

cl_context_properties ourprops[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0 };

contextZ = clCreateContext( ourprops, 1, &dev_idZ[0], clLogMessagesToStdoutAPPLE, NULL, &err );

clbo = clCreateFromGLRenderbuffer( contextZ, CL_MEM_WRITE_ONLY, glboid, &err );

次に、clCreateCommandQueue、clCreateProgramWithBinary、clBuildProgram、clCreateKernel、すべてエラーなし

じゃあ後で:

glFinish();
clEnqueueAcquireGLObjects( queueZ, 1, &clbo, 0,0,0 );

err = clSetKernelArg( kernelZ, 1, sizeof(cl_mem), &clbo );

...これはエラー-38、CL_INVALID_MEM_OBJECTで失敗します。

clboは、相互運用機能がオンになっていないときに使用されるバッファオブジェクトと同様に、静的なcl_memです。違いは、clCreateBufferの代わりにclCreateFromGLRenderbufferを使用して作成され、gl共有グループに関連付けられて作成されたコンテキストにあることです。


(必要に応じて、2番目のRenderbufferを追加し、それをDepth Attachment Pointにアタッチしようとしました。助けにはなりません。)

(FBOにバインドされたテクスチャで同じことを試しましたが、同じ場所で同じエラーが発生します。)

...誰かアイデアはありますか?

4

1 に答える 1

3

Ok; とった!

問題は、カーネルが出力引数として image2d_t ではなく uint * を指定していたことです。少なくとも setkarg 呼び出しでは、これが問題になるとは思いませんでした。どちらもホスト側の cl_mem です (image2d_t は cl_mem として #defined です)。ただし、clCreateFromGLTexture2D または clCreateFromGLRenderbuffer を呼び出すと、そのオブジェクトは、ocl が認識しているプロパティを取得します。カーネルが image2d_t を指定するように変更されたとき、より有用なエラー メッセージが表示され、動作するようになりました。

おまけ: write_imageui; を使用して UNORM_INT8 イメージに書き込むことはできません。write_imagef を使用する必要があります。

于 2012-10-15T17:07:04.523 に答える