我正在使用Haskell和OpenCL编写路径追踪器,但是在将image2d_t传递到我的内核以写入输出时遇到了问题。具体来说,在image2d_t上调用OpenCL中的任何get_image_*函数都会返回无意义的值(通常为0或2^24-1),而write_imagef则不起作用。这仅在GPU上运行时发生--CPU可以正常运行。在主机上调用clGetImageInfo返回正确的值。OpenCL的Haskell绑定将错误代码转换为异常,因此不是忘记检查错误的问题。clinfo将我的版本报告为“OpenCL 1.2 AMD-APP(1084.2)”。值得注意的是,我遇到过(并报告过)多个导致OpenCL编译器崩溃或链接失败的错误,因此这可能是由于这些错误而不是我的代码中的错误导致的。
我像这样初始化OpenCL(希望对不了解Haskell的人相对易懂):
我将这个(稍微简化过的)称之为运行内核并呈现结果的过程:
最后,测试内核:
这将输出一个全屏的四边形,显示GPU内存中随机未初始化的区域。它本应该是一个全屏的青色四边形。我在其中添加了一些
我像这样初始化OpenCL(希望对不了解Haskell的人相对易懂):
(platform:_) <- clGetPlatformIDs
(device:_) <- clGetDeviceIDs platform CL_DEVICE_TYPE_GPU
glContext <- glXGetCurrentContext
glDisplay <- glXGetCurrentDisplay
context <- clCreateContext [CL_GL_CONTEXT_KHR glContext, CL_GLX_DISPLAY_KHR glDisplay] [device] putStrLn
queue <- clCreateCommandQueue context device []
source <- readFile "pt.cl"
program <- clCreateProgramWithSource context source
clBuildProgram program [device] "-cl-strict-aliasing"
`catch` (λe -> case (e :: CLError) of
CL_BUILD_PROGRAM_FAILURE -> putStrLn "Building OpenCL program failed:"
>> clGetProgramBuildLog program device >>= putStrLn
>> throw e
_ -> return ())
kernel <- clCreateKernel program "sample"
pCorners <- mallocArray 4
buffer <- clCreateBuffer context [CL_MEM_READ_ONLY, CL_MEM_USE_HOST_PTR] (4*sizeOf (undefined :: V.Vec4F), castPtr pCorners)
clSetKernelArgSto kernel 1 buffer
tex@(TextureObject texid) <- head <$> (genObjectNames 1)
activeTexture $= TextureUnit 0
textureBinding Texture2D $= Just tex
textureFilter Texture2D $= ((Nearest, Nothing), Nearest)
textureWrapMode Texture2D S $= (Repeated, Clamp)
textureWrapMode Texture2D T $= (Repeated, Clamp)
texImage2D Nothing NoProxy 0 RGBA′ (TextureSize2D initialWidth initialHeight) 0 (PixelData RGBA UnsignedByte nullPtr)
image <- clCreateFromGLTexture2D context [CL_MEM_READ_WRITE] gl_TEXTURE_2D 0 texid
clSetKernelArgSto kernel 2 image
我将这个(稍微简化过的)称之为运行内核并呈现结果的过程:
clSetKernelArgSto kernel 0 position
pokeArray pCorners orientedCorners -- update the pCorners array
finish -- This is glFinish()
clEnqueueAcquireGLObjects queue [image] []
clEnqueueNDRangeKernel queue kernel [width, height] [] []
clEnqueueReleaseGLObjects queue [image] []
clFinish queue
drawElements TriangleFan 4 UnsignedInt offset0
swapBuffers
最后,测试内核:
__kernel void sample(float3 position, __constant float3 corner[4], image2d_t output) {
write_imagef(output, (int2)(get_global_id(0), get_global_id(1)), (float4)(0, 0.5f, 1, 1));
}
这将输出一个全屏的四边形,显示GPU内存中随机未初始化的区域。它本应该是一个全屏的青色四边形。我在其中添加了一些
printf
来显示get_image_*
函数的结果,但它们导致程序挂起。