Image OpenCL映像在OSX中写入

Image OpenCL映像在OSX中写入,image,textures,opencl,Image,Textures,Opencl,我一直在尝试编写一个OpenCL内核,用值填充OpenCL映像。然而,我一直有一些texel没有被写入的问题。我似乎无法让write_image()函数写入具有不同x和y坐标的texel 我在这里创建了一个缩减计划。希望这足够简单易懂: #包括 #包括 #包括 常量字符*clSource[]={ “内核无效集(只写映像2D\t映像)\n”, “{\n”, “int x=get_global_id(0);\n”, “int y=get_global_id(1);\n”, “float4结果=flo

我一直在尝试编写一个OpenCL内核,用值填充OpenCL映像。然而,我一直有一些texel没有被写入的问题。我似乎无法让write_image()函数写入具有不同x和y坐标的texel

我在这里创建了一个缩减计划。希望这足够简单易懂:

#包括
#包括
#包括
常量字符*clSource[]={
“内核无效集(只写映像2D\t映像)\n”,
“{\n”,
“int x=get_global_id(0);\n”,
“int y=get_global_id(1);\n”,
“float4结果=float4(1.0,1.0,1.0,1.0);\n”,
“printf(\“写入维度%d x%d:%d,%d,%d,%d\\n\”,x,y,\n”,
“(int)result.x*255,(int)result.y*255,(int)result.z*255,(int)result.w*255);\n”,
“写入图像f(图像,int2(x,y),结果);\n”,
“}\n”,
};
int main(int argc,const char*argv[]
{
常量无符号整数宽度=3;
常量无符号整数高度=3;
国际文书中心;
cl_平台\u id平台;
clError=clGetPlatformIDs(1和平台,空PTR);
断言(cleror==CL_SUCCESS);
cl_设备\u id设备;
clError=CLGetDeviceID(平台、CL\U设备、类型\U GPU、1和设备、空PTR);
断言(cleror==CL_SUCCESS);
cl_上下文_属性[]={
CL_上下文_平台,(CL_上下文_属性)平台,
0
};
cl_context openCLContext=clCreateContext(属性、1和设备、nullptr、nullptr和cleror);
断言(cleror==CL_SUCCESS);
cl_command_queue commandQueue=clCreateCommandQueue(openCLContext,device,0,&cleror);
断言(cleror==CL_SUCCESS);
cl_program program=clCreateProgramWithSource(openCLContext、sizeof(clSource)/sizeof(const char*)、clSource、nullptr和clError);
断言(cleror==CL_SUCCESS);
clError=clBuildProgram(程序,1,&device,“”,nullptr,nullptr);
断言(cleror==CL_SUCCESS);
cl_kernel kernel=clCreateKernel(程序,“set”和&cleror);
断言(cleror==CL_SUCCESS);
cl_图像_格式图像格式;
imageFormat.image\u channel\u data\u type=CL\u UNORM\u INT8;
imageFormat.image\u channel\u order=CL\u RGBA;
cl_image_desc imageDesc;
imageDesc.image\u type=CL\u MEM\u OBJECT\u IMAGE2D;
imageDesc.image_width=宽度;
imageDesc.image_高度=高度;
imageDesc.image_depth=1;
imageDesc.image\u数组大小=1;
imageDesc.image_行_节距=0;
imageDesc.image\u slice\u pitch=0;
imageDesc.num_mip_levels=0;
imageDesc.num_samples=0;
imageDesc.buffer=nullptr;
cl_mem clTexture=clCreateImage(openCLContext,cl_mem_WRITE_ONLY,&imageFormat,&imageDesc,nullptr,&clError);
断言(cleror==CL_SUCCESS);
cleror=clSetKernelArg(kernel,0,sizeof(cl_mem),&clTexture);
断言(cleror==CL_SUCCESS);
大小\u t globalWorkOffset[]={0,0,0};
size_t globalWorkSize[]={宽度,高度,0};
大小\u t localWorkSize[]={1,1,0};
cl_事件1;
cleror=clenqueueendrangekernel(commandQueue、kernel、2、globalWorkOffset、globalWorkSize、localWorkSize、0、nullptr和event1);
断言(cleror==CL_SUCCESS);
无符号字符*位图=新的无符号字符[宽度*高度*4];
原点的大小[]={0,0,0};
区域大小[]={宽度,高度,1};
cl_事件2;
clError=CLENQUEUREADIMAGE(命令队列、clTexture、CL_TRUE、原点、区域、0、0、位图、1、&event1和&event2);

std::cout问题在于构建向量值的方式。而不是这样:

typeN(a, b, ..., k)
您应该这样做:

(typeN)(a, b, ..., k)
前者实际上会在非苹果平台上导致编译错误,所以我不确定苹果的编译器是如何解释这些代码的

因此,对于内核,需要更改的两行相关代码如下:

float4 result = float4(1.0, 1.0, 1.0, 1.0);
...
write_imagef(image, int2(x, y), result);
现在应该变成:

float4 result = (float4)(1.0, 1.0, 1.0, 1.0);
...
write_imagef(image, (int2)(x, y), result);

通过以下内核更改,我成功编译并运行了您的程序:

const char* clSource[] = {
    "__kernel void set(write_only image2d_t image)\n",
    "{\n",
    "    int x = get_global_id(0);\n",
    "    int y = get_global_id(1);\n",
    "    float4 result = (float4)(1.0, 1.0, 1.0, 1.0);\n",
    "    printf(\"Writing dimensions %d x %d: %d, %d, %d, %d\\n\", x, y,\n",
    "        (int)result.x*255, (int)result.y*255, (int)result.z*255, (int)result.w*255);\n",
    "    write_imagef(image, (int2)(x, y), result);\n",
    "}\n",
};
例如,您不能编写float4(1.0…),但必须将其编写为C样式的类型转换(float4)。我不知道为什么它甚至可以用您的驱动程序干净地编译

输出中另一个非常奇怪的问题是,您的输出似乎来自第23行的宽度和高度为3的情况。输出是否来自确实为3的版本


不管怎样,在更改后它仍然可以正常工作。

Re:2 vs 3:是的,我在粘贴输出之前将2更改为3,然后忘记在原始源代码中更改。我已经更新了问题。我很高兴有人对此进行了解释;这也让我感到奇怪。感谢您让我们知道!GLSL vs OpenCL再次出击!
const char* clSource[] = {
    "__kernel void set(write_only image2d_t image)\n",
    "{\n",
    "    int x = get_global_id(0);\n",
    "    int y = get_global_id(1);\n",
    "    float4 result = (float4)(1.0, 1.0, 1.0, 1.0);\n",
    "    printf(\"Writing dimensions %d x %d: %d, %d, %d, %d\\n\", x, y,\n",
    "        (int)result.x*255, (int)result.y*255, (int)result.z*255, (int)result.w*255);\n",
    "    write_imagef(image, (int2)(x, y), result);\n",
    "}\n",
};