OS XのOpenCL - その10 [OS XのOpenCL]
OS XでのOpenCLプログラミングガイド抄訳の続き。今日のところは画像操作に特化したメモリオブジェクトの使い方。
この章ではホストメモリにある画像データを取りだしてカーネルがアクセスできるイメージオブジェクトに配置する方法を説明する。また、この画像データを処理する方法についての概説もおこなう。これらの関数の引数に関する概念的な記述は「OS XのOpenCLでのイメージとバッファを表すパラメータ」参照。
7 OpenCLのイメージオブジェクトを作成し使用する
OpenCLには画像データを処理するビルトインのサポートがある。イメージオブジェクトを使えば、ホストメモリにある画像データをとってきてOpenCLデバイスで実行しているカーネルに処理させることができる。イメージオブジェクトはたくさんの画像フォーマットをネイティブにサポートしているので、イメージオブジェクトは画像データを表現してアクセスするプロセスを簡単化する。もし画像データに対して効率的に計算を実行する必要があるなら、OS XでのOpenCLの画像に対するネイティブサポートが便利であることがわかるだろう。この章ではホストメモリにある画像データを取りだしてカーネルがアクセスできるイメージオブジェクトに配置する方法を説明する。また、この画像データを処理する方法についての概説もおこなう。これらの関数の引数に関する概念的な記述は「OS XのOpenCLでのイメージとバッファを表すパラメータ」参照。
7.1 OpenCLでのイメージの作成と使用
イメージオブジェクトを作るにはgcl_create_imageを使う。この関数は2次元と3次元のイメージオブジェクトを作るのに使える。2次元のイメージを指定するには image_depth引数を0に設定する。3次元の場合はimage_depthをピクセルにする。io_surface引数にIOSurfaceRefを渡したら渡したIOSurfaceを使ってイメージを作成する。そうでなければio_surface引数はNULLに設定する。cl_image gcl_create_image( const cl_image_format *image_format, size_t image_width, size_t image_height, size_t image_depth, IOSurfaceRef io_surface );
- image_format
- OpenCLのイメージフォーマットデスクリプタ
- image_width
- ピクセル単位の画像の幅
- image_height
- ピクセル単位の画像の高さ
- image_depth
- ピクセル単位の画像の深さ
- io_surface
- IOSurfaceRefを渡せばそれでイメージを作成する。それ以外はNULL
7.2 イメージオブジェクトの読み書きコピー
イメージオブジェクトを作った後はホストメモリとの間で読んだり書いたりコピーしたりということをキューに投入できる。ホストアプリからは次の関数が使える:- 二つのイメージの間やひとつのイメージのある部分から別の部分へのコピーは、
void gcl_copy_image( cl_image dst_image, cl_image src_image, const size_t dst_origin[3], const size_t src_origin[3], const size_t region[3]);
コピーはsrc_origin(x,y,zの値をとる)からはじまってdst_origin(同様にx,y,zの値)の位置へ書き込まれる。コピーはregionで指定された2次元あるいは3次元の長方形領域にわたって行われる。イメージ間のコピーなので全てのパラメータはピクセル単位である。 - イメージのデータをバッファへコピーするには
void gcl_copy_image_to_ptr( void *buffer_ptr, cl_image src_image, const size_t src_origin[3], const size_t region[3]);
buffer_ptr引数はコピー先のバッファを指す。src_imageはコピー元のイメージである。src_originはコピーされる原点のピクセル位置である。regionはコピー領域である。イメージからのコピーなので、単位はピクセルである。
例えば、4x4ピクセルのイメージがあって、それぞれのピクセルが4バイト占めていて、それぞれのバイトが赤緑青とアルファチャンネルとする。この例ではイメージデータの部分を取り出すとして、例えば3ピクセル幅で2ピクセル高さで、1,1の位置から始めるとすると、図-にあるように、グレーのピクセルではなく明るい緑と暗い緑のピクセルをコピーすることになる。
イメージは1ピクセル4バイトで、コピーは3 ×2=6ピクセルなので、バッファは少なくとも6 ×4 = 24バイト収容可能でなければならない。
呼び出しは次のようになる:const size_t origin[3] = { 1, 1, 0 }; const size_t region[3] = { 3, 2, 1}; gcl_copy_image_to_ptr(our_buffer, the_image, origin, region);
- originの最後の要素origin[2]は0に設定される。これは2次元のイメージを扱っているからである(もし、3次元のイメージなら3番目の次元のための数が渡されるはずである)
- もし2次元のイメージをコピーするならregion[2]は1に設定される。このことはバッファの中では幅3、高さ2、深さ1のピクセルの画像スライスとなる。2次元のイメージでは幅と高さのピクセルのサイズを持ったひとつの「画像スライス」であるため、region[2]は1である。もし2に設定されたなら、ピクセル数は倍になって、ピクセルの「スタック」にもうひとつ「深い」スライスがあるということになる。
- バッファからイメージにコピーするには
void gcl_copy_ptr_to_image( cl_image dst_image, void *src_buffer_ptr, const size_t dst_origin[3], const size_t buffer_region[3]);
gcl_copy_ptr_to_imageの引数は、イメージがコピー先でバッファがコピー元である以外はgcl_copy_image_to_ptrと同じである。
2015-06-18 21:30
nice!(0)
コメント(0)
トラックバック(0)
コメント 0