[Mesa-dev] OpenCL Image Support Question about 'soft_copy_op'
Dorrington, Albert
albert.dorrington at lmco.com
Mon Mar 31 11:39:26 PDT 2014
I am experimenting with adding image support to Mesa and am encountering something I don't understand with the mapping routines implemented in transfer.cpp, within the soft_copy_op function.
We are working on 10.1 branch of Mesa which has some tweaks to let Mesa run OpenCL kernels build from the AMD OpenCL driver, so my issues may very well be an artifact of that environment.
In any case, here is what I am seeing:
I have a simple program which generates an image of a given size, and sets each pixel to a value from a given starting point with a given increment value.
For example, the command "imageTest 32 32 0 1" would create a 32x32 image, in which pixel (0,0) would be set to 0, (0,1)=1 ... (0,31)=31, (1,0)=32 and so on...
The kernel takes the x,y coordinates as parameters and returns the value at that location.
It appears that the default soft_copy_op destination mapping does not provide a compatible setup for images.
Given a 32x32 image of format CL_R8, INT32, the validate_object() routines in clEnqueueWriteImage() calculate a destination pitch of {4,128,4096}
This results in a size of 4096 being passed to the mapping get (dst_pitch[2]*region[2]) this generates a staging texture of 4096x1x1 pixels.
With this, I can retrieve the values from the first row of the image, but none of the subsequent rows return valid values.
After some experimentation (with a 64x4 image) I discovered that there appears to be a minimum row pitch of 256bytes, so the 128 being passed in for the 32x32 image didn't work properly.
I changed the clEnqueueWrite routine to adjust the destination pitches as follows:
dst_pitch[1]= MAX2(256,dst_pitch[1]); // row pitch
dst_pitch[2]=dst_pitch[1]*region[1]; // slice pitch
That seemed to work at first, but once I started moving to different image sizes, things did not work right at all...
With a 64x64 image, the subsequent rows no longer mapped properly.
After more experimentation, I seem to have found a method that will work reliably, with testing of images up to 2048x2048. (I can't seem to go higher than that, due to a memory leak I have not found yet...)
What I did, was add a different mapping get template for images:
template<>
struct _map<clover::image*> {
static mapping
get(command_queue &q, clover::image *img, cl_map_flags flags, size_t offset, size_t size) {
return { q, img->resource(q), flags, true, {{offset}}, {{size, size, 1}} };
}
}
Then, in the soft_copy_op routine, instead of passing in the slice pitch size, I pass in MAX2(region[0],region[1]).
I'd rather pass in the entire vector for the region, but I didn't want to rework the other mapping get routines in the template quite yet...
This works, as long as my images are square... but once I move to different dimensions (ie 32x64, 64x128) my second row of data is off again...
I'm assuming this is because of passing the largest dimension in for the mapping get routine, rather than the width and height....
I feel like I'm misunderstanding how these mapping routines are supposed to be working.
I'm also concerned that as the image sizes grow, that the use of the 'memcpy' will be very inefficient (as opposed to a DMA copy)
I'm hoping someone might be able to explain a bit about these mapping routines, and perhaps shed some light on the OpenGL image transfer routines and how they might be accessible from the OpenCL side.
Thanks for reading my rambling message! :)
Al Dorrington
Software Engineer Sr
Lockheed Martin, Mission Systems and Training
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20140331/b5e88b7d/attachment-0001.html>
More information about the mesa-dev
mailing list