opencl - 多次使用图像

opencl - using image multiple times

所以我想制作一个显示一些图像的应用程序,当 window 调整大小时,它也会缩放所有图像以适合屏幕。 我的策略是:

  1. 为每个原始图像调用 clCreateImage 并将 cl_mem 指针存储在全局地图中(类似于:filename -> cl_mem
  2. 调用scale(cl_mem img, int width, int height),调用内核并读取输出图像数据。然后显示缩放后的图像。
  3. 当 window 调整大小事件发生时:删除所有缩放的图像并再次调用 scale(...)cl_mem 指针存储在地图中

我在小规模上尝试过,我只创建了一张图片,然后调用了两次 scale。第一个是好的并且缩放了,但是第二个是损坏的。不知道为什么,src图片是CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,out图片是在scale函数中创建的

原文:https://ibb.co/pQDwScW

第一次缩放(以适应 300x300):https://ibb.co/nnN9kTY

第二次尝试(适合 500x500):https://ibb.co/561SkSn

但是当我只尝试 300x300 然后又尝试 300x300 时它也被损坏了。 有没有规定,图像不能在内核中多次使用?或者我只是遗漏了什么?

编辑:

C 代码在这里:https://pastebin.com/NpSaxRyT

它是从golang和cgo一起使用的,所以createImage returns cl_mem as void*,所以Go部分不需要包含cl.h.

init() 函数在 Go 程序启动时被调用。 createImage 使用像素数据从 Go 调用函数。

因此图像指针(cl_mem 指针)在 Go 中,然后调用 resize (scale) 函数。它采用将传输像素数据的 void* 指针和缓冲区指针。 缓冲区也是由 Go 分配的,但是第一张图片没问题,我认为 GC 没有启动(也尝试完全禁用 GC)。

像这样:

    outData := make([]byte, outWidth*outHeight*ir.pixelSize)
    ret := C.resize(
        cl_mem_img_pointer, //unsafe.Pointer (void*)
        C.int(origWidth),
        C.int(origHeight),
        C.int(outWidth),
        C.int(outHeight),
        C.int(rowPitch),
        C.uint(image_channel_order),
        C.uint(image_channel_data_type),
        unsafe.Pointer(&outData[0]),
    )

您在第一次调整大小操作后立即释放

if err := ir.Release(); err != nil {
    t.Fatal(err)
}

img2, err := ir.Resize(200, 200)
if err != nil {
    t.Fatal(err)
}

并且 200x200 调整大小失败,因为它找不到已发布的 img 组件。

在您退出程序之前,所有 OpenCL 对象都是 re-usable。退出前,别忘了释放 reverse-order 分配的资源。

如果您只对所有任务使用同一个内核,则可以只使用一个全局内核对象来用于所有调整大小调用。它只需要 re-setting 个在调用之间更改的内核参数。例如,更改输出图像的大小、图像缓冲区本身等