5

CUDA ツールキット 4.0 を搭載した Geforce 330M でテクスチャの OpenCL-OpenGL 相互運用を試しています。

Image2Dフレームをキャプチャし、そのデータをOpenCL カーネルへの入力画像 ( ) として使用します。カーネルはデータを操作し、Image2DGLOpenGL テクスチャが添付された画像オブジェクトである に書き込む必要があります。基本的には次のようになります。

 _______________      RGB        _______________
|               |    uint8*     |               |   CL_RGBA / CL_UNORM_INT8
|   Grabber     | ------------> |   Image2D     | -------------------------.
|   avcodec     |               |   [input]     |                          |
|_______________|               |_______________|                          |
                                                                           |    
                                                                           V
 _______________                 _______________                       _______________
|               |               |               |                     |               |
|   Texture     | ------------> |   Image2DGL   | <-----------------> |    Kernel     |
|_______________|               |   [output]    |                     |_______________|
                                |_______________|
Internal
Format: GL_RGBA
Format: GL_RGBA
Type: ?

私はそのようなテクスチャを初期化しています:

GLuint tex = 0;

void initTexture( int width, int height )
{
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_RECTANGLE, tex);
// now here is where I need assistance: The type parameter of the Texture (GL_FLOAT)
    glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, NULL );
} 


編集:私もタイプを持つことができGL_UNSIGNED_INTます。


次に、共有イメージ ( Image2DGL)を作成します。

texMems.push_back(Image2DGL(clw->context, CL_MEM_READ_WRITE, GL_TEXTURE_RECTANGLE, 0, tex, &err));

次に、ソース イメージ (入力イメージ) を作成します。

ImageFormat format;
format.image_channel_data_type = CL_UNORM_INT8;
format.image_channel_order = CL_RGBA;
srcImgBuffer = Image2D(clw->context, CL_MEM_READ_WRITE, format, width, height, 0, NULL, &err);

すべてのレンダリングループで、データをに書き込んでいますsrcImgBuffer:

// write the frame to the image buffer
clw->queue.enqueueWriteImage(srcImgBuffer, CL_TRUE, origin, region, 0, 0, (void*)data, NULL, NULL);

また、カーネルの引数を設定しています:

tex_kernel.setArg(0, texMems[0]);
tex_kernel.setArg(1, srcImgBuffer);
tex_kernel.setArg(2, width);
tex_kernel.setArg(3, height);

GLオブジェクトを取得して解放する前と後。テスト用カーネルは次のようになります。

__kernel void init_texture_kernel(__write_only image2d_t out, __read_only image2d_t in, int w, int h)
{
    const sampler_t smp = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;

    int2 coords = { get_global_id(0), get_global_id(1) };
    float4 pixel = read_imagef(in, smp, coords);
    float4 test = { (float)coords.x/(float)w , 0, 0, 1};
    write_imagef( out, coords, pixel );
}

image_channel_data_typeカーネルでは float として読み取ることができ、正規化された値として解釈されます。出力画像が正しくないように見えます。明らかにデータの解釈が間違っているため、(線ごとに) スライスされた画像が表示されます。前述したように、エラーはテクスチャのタイプの初期化にあると想定しています。GL_FLOAT を試しました (カーネル内のイメージにフロートとして書いているため)。

結果: デコーダーからの PPM ダンプとしての画像 (左)、分散したテクスチャ出力 (右)

PPMはデコーダーから出力されたもので、右は出力テクスチャに返されたものです。

誰かが実際にここまで読んだ場合: 問題を解決するためのテクスチャのタイプに関する提案はありますか?


編集:キャプチャしたフレームをテクスチャに直接バインドすると、ビデオは正常に再生されます。つまり、CL-GL インターフェースに何らかの関係があるに違いありません。


4

2 に答える 2

2

glTexture2D への最後の引数が NULL の場合、フォーマットとタイプの引数は有効な OpenGL フォーマット/タイプにすることができますが、それらは使用されず、何にも影響しません。浮動小数点テクスチャが必要な場合は、正しい internal_format 引数を渡して指定する必要があります。

glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
于 2012-01-30T16:39:33.317 に答える
1

私は最終的に解決策を思いつきましたが、明らかなことはわかりませんでした。RGBビデオがありました。そのため、フレームを RGB でキャプチャしました。これは、テクスチャに問題なく表示できます。ただし、(カーネル コードで見られるように) チャネルが 3 つしか存在しないバッファから一度にaを取得するfloat4と、もちろん台無しになります。ああ。

行数を見て間違いを推測することもできました: 要求された行数 512 行のうち 384 行を取得しました.75

グラバー (libavcodec を使用) に RGBA を取得するように要求しただけで、4 チャンネルの画像が得られるようにパディングされました。

この質問はクローズするようにフラグを立てます。

于 2012-02-01T16:10:48.930 に答える