2012-08-08 95 views
0

我正在开发一些与图像缓冲区一起工作的内核。问题是,当我通过直接复制图像的数据创建我的Image2D时,一切正常。在GPU上enqueueWriteImage失败

如果我尝试写入我的图像缓冲区,它将不适用于我的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(英特尔酷睿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); 

发送的数据是一个大小为012的int数组。我此代码得到它:

DataBufferInt dataBuffer = (DataBufferInt)image.getRaster().getDataBuffer(); 
int data[] = dataBuffer.getData(); 

上面的代码是在使用JOCL java中,同样的问题出现在使用C++的OpenCL包装的另一C++程序。唯一的区别是在Java中虚拟机崩溃(在3〜4帧之后)并且在C++中结果是黑色图像。

+0

你是否从clxx函数中得到y错误或状态码?你可以分享主机代码的相关部分,关于你如何设置图像和入队缓冲区? – 2012-08-08 16:36:47

+0

状态代码在C++中都是清晰的,在java中没有抛出异常(使用'CL.setExceptionsEnabled(true);')。我开始认为问题可能来自驱动程序或OpenCL实现。 – dkg 2012-08-10 08:43:33

回答

2

嗯,我发现了这个问题。那是我的司机行为怪异。

我使用的是12.4版本(我开始使用OpenCL时安装的版本),我刚安装了12.6版本,问题就消失了。

因此,请保持您的驱动程序是最新的!