画像バッファで動作するいくつかのカーネルを開発しています。問題は、画像のデータを直接コピーして Image2D を作成すると、すべてがうまく機能することです。
イメージ バッファへの書き込みをエンキューしようとしても、GPU では機能しません。
基本的なカーネルは次のとおりです。
__kernel void myKernel(__read_only image2d_t in, __write_only image2d_t out) {
const int x = get_global_id(0);
const int y = get_global_id(1);
const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;
uint4 pixel = read_imageui(in, sampler, (int2)(x, y));
write_imageui(out, (int2)(x, y), pixel);
}
その単純なカーネルは、GPU では黒いイメージを与えますが、CPU ではうまく機能します。
それを機能させるには、バッファ イメージを解放し、CL_MEM_COPY_HOST_PTR
. 私は適切なデータ形式を使用しています:CL_RGBA、CL_UNSIGNED_INT8、画像のサイズは適切です。
この問題は、JOCL および API の C++ バインディングで発生しています。(C API はテストしていません)。
最後に、バッファを再作成して実行しますが、それは良い考えですか? それは普通ですか?それを避けるためにどのアクションを実行できますか?
ちなみに、Intel SDK for OpenCL (Intel Core I7) と ATI AMD APP SDK (HD6800) で実行しています。
[編集]
これは、バッファに書き込むために使用するコードです。
まず、割り当て部分:
cl_image_format imageFormat = new cl_image_format();
imageFormat.image_channel_order = CL_RGBA;
imageFormat.image_channel_data_type = CL_UNSIGNED_INT8;
inputImageMem = clCreateImage2D(
context, CL_MEM_READ_ONLY,
new cl_image_format[]{imageFormat}, imageSizeX, imageSizeY,
0, null, null);
そして、実行時にフレームごとに呼び出される、GPU で動作しない部分:
clEnqueueWriteImage(commandQueue, inputImageMem, CL_TRUE, new long[]{0, 0, 0},
new long[]{imageSizeX, imageSizeY, 1}, 0, 0,
Pointer.to(data), 0, null, null);
GPU と CPU の両方で動作するが、バッファの再作成を強制する部分:
clReleaseMemObject(inputImageMem);
cl_image_format imageFormat = new cl_image_format();
imageFormat.image_channel_order = CL_RGBA;
imageFormat.image_channel_data_type = CL_UNSIGNED_INT8;
inputImageMem = clCreateImage2D(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, new cl_image_format[]{imageFormat}, imageSizeX, imageSizeY, 0, Pointer.to(data), null);
送信されるデータは、サイズが int の配列ですimageSizeX*imageSizeY
。私はこのコードでそれを取得します:
DataBufferInt dataBuffer = (DataBufferInt)image.getRaster().getDataBuffer();
int data[] = dataBuffer.getData();
上記のコードは JOCL を使用する Java であり、C++ OpenCL ラッパーを使用する別の C++ プログラムでも同じ問題が発生します。唯一の違いは、Java では仮想マシンがクラッシュし (3 ~ 4 フレーム後)、C++ では結果が黒いイメージになることです。