我在单独的内核中实现了一些过滤器,并在ping-pang方案中使用了两个图像缓冲区,就像在内核中和在输出中一样。但是,有些内核被“忽略”(仅被忽略以按正确的顺序读取输出,但仍基于调试输出执行。)我应该怎么做或者应该设置哪种条件来使其同步?
三个过滤器内核 Median_kernel , HPass_x_kernel 和 HPass_y_kernel 如果我仅将其中一个排入队列并注释了另外两个,则它们可以正常工作从内核代码应该不会有什么问题。
我尝试将不同的新图像缓冲区用作每个内核的in /输出,它也可以工作。但是对我来说,这将是解决此问题的愚蠢方法:(
内核设置代码如下:其中InBuffer和OutBuffer也是格式为
的图像缓冲区
const cl :: ImageFormat格式(CL_RGBA,CL_UNSIGNED_INT8);
const cl::ImageFormat format(CL_RGBA, CL_HALF_FLOAT);
YUVImg1 = cl::Image2D(context, CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, format, m_width, m_height, 0, 0);
YUVImg2 = cl::Image2D(context, CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, format, m_width, m_height, 0, 0);
DeNoiseImage = cl::Image2D(context, CL_MEM_READ_WRITE, format, m_width, m_height, 0, 0);
R2Y_kernel = cl::Kernel(program, "rgba2yuv");
R2Y_kernel.setArg(0, InBuffer);
R2Y_kernel.setArg(1, YUVImg2);
Median_kernel = cl::Kernel(program, "MedianFilter");
Median_kernel.setArg(0, YUVImg2);
Median_kernel.setArg(1, YUVImg1);
HPass_x_kernel = cl::Kernel(program, "HighPass_x");
HPass_x_kernel.setArg(0, YUVImg1);
HPass_x_kernel.setArg(1, YUVImg2);
HPass_y_kernel = cl::Kernel(program, "HighPass_y");
HPass_y_kernel.setArg(0, YUVImg2);
HPass_y_kernel.setArg(1, YUVImg1);
Y2R_kernel = cl::Kernel(program, "yuv2rgba");
Y2R_kernel.setArg(0, YUVImg1);
Y2R_kernel.setArg(1, OutBuffer);
Y2R_kernel.setArg(2, DeNoiseImage);
这是命令队列代码:
cl::size_t<3> origin;
origin[0] = 0;
origin[1] = 0;
origin[2] = 0;
cl::size_t<3> region;
region[0] = m_width;
region[1] = m_height;
region[2] = 1;
commandQueue.enqueueNDRangeKernel(
R2Y_kernel,
cl::NullRange,
cl::NDRange(m_width, m_height),
cl::NDRange(m_blockSizeX, m_blockSizeY),
NULL);
commandQueue.enqueueNDRangeKernel(
Median_kernel,
cl::NullRange,
cl::NDRange(m_width, m_height),
cl::NDRange(16, 4),
NULL);
commandQueue.enqueueNDRangeKernel(
HPass_x_kernel,
cl::NullRange,
cl::NDRange(m_width, m_height),
cl::NDRange(m_blockSizeX, m_blockSizeY),
NULL);
commandQueue.enqueueNDRangeKernel(
HPass_y_kernel,
cl::NullRange,
cl::NDRange(m_width, m_height),
cl::NDRange(m_blockSizeX, m_blockSizeY),
NULL);
commandQueue.enqueueNDRangeKernel(
Y2R_kernel,
cl::NullRange,
cl::NDRange(m_width, m_height),
cl::NDRange(m_blockSizeX, m_blockSizeY),
NULL);
硬件信息: 供应商:Advanced Micro Devices,Inc. 设备OpenCL C版本:OpenCL C 2.0 驱动程序版本:2874.0(HSA1.1,LC) 个人资料:FULL_PROFILE 版本:OpenCL 1.2
当前输出是未过滤的图像帧。但是,根据调试消息,命令队列以排队的顺序执行。
另一个奇怪的事情是,在其他内核(也包括图像过滤器)的主计算链中,我使用的是相同的ping-pang方案,并且工作得很好。唯一的区别是,几乎所有其他过滤器在宿主代码中都创建了相同的类,但是相同的(读和写)图像缓冲区指针传递给了这些类,因此它应该仍然是相同的概念:(