* Threshold the rectangle, taking everything except the image buffer pointer * from the class, using thresholds/hi_values to the output IMAGE. * only supports 1 or 4 channels ************************************************************************/
| 1929 | * only supports 1 or 4 channels |
| 1930 | ************************************************************************/ |
| 1931 | int OpenclDevice::ThresholdRectToPixOCL(unsigned char *imageData, |
| 1932 | int bytes_per_pixel, int bytes_per_line, |
| 1933 | int *thresholds, int *hi_values, |
| 1934 | Pix **pix, int height, int width, |
| 1935 | int top, int left) { |
| 1936 | PERF_COUNT_START("ThresholdRectToPixOCL") |
| 1937 | int retVal = 0; |
| 1938 | /* create pix result buffer */ |
| 1939 | *pix = pixCreate(width, height, 1); |
| 1940 | uint32_t *pixData = pixGetData(*pix); |
| 1941 | int wpl = pixGetWpl(*pix); |
| 1942 | int pixSize = wpl * height * sizeof(uint32_t); // number of pixels |
| 1943 | |
| 1944 | cl_int clStatus; |
| 1945 | KernelEnv rEnv; |
| 1946 | SetKernelEnv(&rEnv); |
| 1947 | |
| 1948 | /* setup work group size parameters */ |
| 1949 | int block_size = 256; |
| 1950 | cl_uint numCUs = 6; |
| 1951 | clStatus = clGetDeviceInfo(gpuEnv.mpDevID, CL_DEVICE_MAX_COMPUTE_UNITS, |
| 1952 | sizeof(numCUs), &numCUs, NULL); |
| 1953 | CHECK_OPENCL(clStatus, "clCreateBuffer imageBuffer"); |
| 1954 | |
| 1955 | int requestedOccupancy = 10; |
| 1956 | int numWorkGroups = numCUs * requestedOccupancy; |
| 1957 | int numThreads = block_size * numWorkGroups; |
| 1958 | size_t local_work_size[] = {(size_t)block_size}; |
| 1959 | size_t global_work_size[] = {(size_t)numThreads}; |
| 1960 | |
| 1961 | /* map imagedata to device as read only */ |
| 1962 | // USE_HOST_PTR uses onion+ bus which is slowest option; also happens to be |
| 1963 | // coherent which we don't need. |
| 1964 | // faster option would be to allocate initial image buffer |
| 1965 | // using a garlic bus memory type |
| 1966 | cl_mem imageBuffer = clCreateBuffer( |
| 1967 | rEnv.mpkContext, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, |
| 1968 | width * height * bytes_per_pixel * sizeof(char), imageData, &clStatus); |
| 1969 | CHECK_OPENCL(clStatus, "clCreateBuffer imageBuffer"); |
| 1970 | |
| 1971 | /* map pix as write only */ |
| 1972 | pixThBuffer = |
| 1973 | clCreateBuffer(rEnv.mpkContext, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, |
| 1974 | pixSize, pixData, &clStatus); |
| 1975 | CHECK_OPENCL(clStatus, "clCreateBuffer pix"); |
| 1976 | |
| 1977 | /* map thresholds and hi_values */ |
| 1978 | cl_mem thresholdsBuffer = |
| 1979 | clCreateBuffer(rEnv.mpkContext, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, |
| 1980 | bytes_per_pixel * sizeof(int), thresholds, &clStatus); |
| 1981 | CHECK_OPENCL(clStatus, "clCreateBuffer thresholdBuffer"); |
| 1982 | cl_mem hiValuesBuffer = |
| 1983 | clCreateBuffer(rEnv.mpkContext, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, |
| 1984 | bytes_per_pixel * sizeof(int), hi_values, &clStatus); |
| 1985 | CHECK_OPENCL(clStatus, "clCreateBuffer hiValuesBuffer"); |
| 1986 | |
| 1987 | /* compile kernel */ |
| 1988 | if (bytes_per_pixel == 4) { |
no test coverage detected