int process_cl(struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, cl_mem dev_in, cl_mem dev_out, const dt_iop_roi_t *roi_in, const dt_iop_roi_t *roi_out) { dt_iop_bilat_data_t *d = (dt_iop_bilat_data_t *)piece->data; // the total scale is composed of scale before input to the pipeline (iscale), // and the scale of the roi. const float scale = piece->iscale / roi_in->scale; const float sigma_r = d->sigma_r; // does not depend on scale const float sigma_s = d->sigma_s / scale; cl_int err = -666; dt_bilateral_cl_t *b = dt_bilateral_init_cl(piece->pipe->devid, roi_in->width, roi_in->height, sigma_s, sigma_r); if(!b) goto error; err = dt_bilateral_splat_cl(b, dev_in); if(err != CL_SUCCESS) goto error; err = dt_bilateral_blur_cl(b); if(err != CL_SUCCESS) goto error; err = dt_bilateral_slice_cl(b, dev_in, dev_out, d->detail); if(err != CL_SUCCESS) goto error; dt_bilateral_free_cl(b); return TRUE; error: dt_bilateral_free_cl(b); dt_print(DT_DEBUG_OPENCL, "[opencl_bilateral] couldn't enqueue kernel! %d\n", err); return FALSE; }
int process_cl (struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, cl_mem dev_in, cl_mem dev_out, const dt_iop_roi_t *roi_in, const dt_iop_roi_t *roi_out) { dt_iop_monochrome_data_t *d = (dt_iop_monochrome_data_t *)piece->data; dt_iop_monochrome_global_data_t *gd = (dt_iop_monochrome_global_data_t *)self->data; cl_int err = -999; const int devid = piece->pipe->devid; const int width = roi_out->width; const int height = roi_out->height; const float sigma2 = (d->size*128.0)*(d->size*128.0f); // TODO: alloc new buffer, bilat filter, and go on with that const float scale = piece->iscale/roi_in->scale; const float sigma_r = 250.0f; // does not depend on scale const float sigma_s = 20.0f / scale; const float detail = -1.0f; // bilateral base layer cl_mem dev_tmp = NULL; dev_tmp = dt_opencl_alloc_device(devid, roi_in->width, roi_in->height, 4*sizeof(float)); dt_bilateral_cl_t *b = dt_bilateral_init_cl(devid, roi_in->width, roi_in->height, sigma_s, sigma_r); if(!b) goto error; size_t sizes[2] = { ROUNDUPWD(width), ROUNDUPHT(height) }; dt_opencl_set_kernel_arg(devid, gd->kernel_monochrome_filter, 0, sizeof(cl_mem), &dev_in); dt_opencl_set_kernel_arg(devid, gd->kernel_monochrome_filter, 1, sizeof(cl_mem), &dev_tmp); dt_opencl_set_kernel_arg(devid, gd->kernel_monochrome_filter, 2, sizeof(int), &width); dt_opencl_set_kernel_arg(devid, gd->kernel_monochrome_filter, 3, sizeof(int), &height); dt_opencl_set_kernel_arg(devid, gd->kernel_monochrome_filter, 4, sizeof(float), &d->a); dt_opencl_set_kernel_arg(devid, gd->kernel_monochrome_filter, 5, sizeof(float), &d->b); dt_opencl_set_kernel_arg(devid, gd->kernel_monochrome_filter, 6, sizeof(float), &sigma2); err = dt_opencl_enqueue_kernel_2d(devid, gd->kernel_monochrome_filter, sizes); if(err != CL_SUCCESS) goto error; err = dt_bilateral_splat_cl(b, dev_tmp); if (err != CL_SUCCESS) goto error; err = dt_bilateral_blur_cl(b); if (err != CL_SUCCESS) goto error; err = dt_bilateral_slice_cl(b, dev_tmp, dev_tmp, detail); if (err != CL_SUCCESS) goto error; dt_bilateral_free_cl(b); b = NULL; // make sure we don't do double cleanup in case the next few lines err out dt_opencl_set_kernel_arg(devid, gd->kernel_monochrome, 0, sizeof(cl_mem), &dev_in); dt_opencl_set_kernel_arg(devid, gd->kernel_monochrome, 1, sizeof(cl_mem), &dev_tmp); dt_opencl_set_kernel_arg(devid, gd->kernel_monochrome, 2, sizeof(cl_mem), &dev_out); dt_opencl_set_kernel_arg(devid, gd->kernel_monochrome, 3, sizeof(int), &width); dt_opencl_set_kernel_arg(devid, gd->kernel_monochrome, 4, sizeof(int), &height); dt_opencl_set_kernel_arg(devid, gd->kernel_monochrome, 5, sizeof(float), &d->a); dt_opencl_set_kernel_arg(devid, gd->kernel_monochrome, 6, sizeof(float), &d->b); dt_opencl_set_kernel_arg(devid, gd->kernel_monochrome, 7, sizeof(float), &sigma2); dt_opencl_set_kernel_arg(devid, gd->kernel_monochrome, 8, sizeof(float), &d->highlights); err = dt_opencl_enqueue_kernel_2d(devid, gd->kernel_monochrome, sizes); if(err != CL_SUCCESS) goto error; if (dev_tmp != NULL) dt_opencl_release_mem_object(dev_tmp); return TRUE; error: if (dev_tmp != NULL) dt_opencl_release_mem_object(dev_tmp); dt_bilateral_free_cl(b); dt_print(DT_DEBUG_OPENCL, "[opencl_monochrome] couldn't enqueue kernel! %d\n", err); return FALSE; }
int process_cl (struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, cl_mem dev_in, cl_mem dev_out, const dt_iop_roi_t *roi_in, const dt_iop_roi_t *roi_out) { dt_iop_lowpass_data_t *d = (dt_iop_lowpass_data_t *)piece->data; dt_iop_lowpass_global_data_t *gd = (dt_iop_lowpass_global_data_t *)self->data; cl_int err = -999; const int devid = piece->pipe->devid; const int width = roi_in->width; const int height = roi_in->height; const int channels = piece->colors; const float Labmax[] = { 100.0f, 128.0f, 128.0f, 1.0f }; const float Labmin[] = { 0.0f, -128.0f, -128.0f, 0.0f }; const int use_bilateral = d->radius < 0 ? 1 : 0; const float radius = fmax(0.1f, fabs(d->radius)); const float sigma = radius * roi_in->scale / piece ->iscale; const float saturation = d->saturation; const int order = d->order; size_t sizes[3]; cl_mem dev_m = NULL; cl_mem dev_coeffs = NULL; dt_gaussian_cl_t *g = NULL; dt_bilateral_cl_t *b = NULL; if(!use_bilateral) { g = dt_gaussian_init_cl(devid, width, height, channels, Labmax, Labmin, sigma, order); if(!g) goto error; err = dt_gaussian_blur_cl(g, dev_in, dev_out); if(err != CL_SUCCESS) goto error; dt_gaussian_free_cl(g); g = NULL; } else { const float sigma_r = 100.0f; // does not depend on scale const float sigma_s = sigma; const float detail = -1.0f; // we want the bilateral base layer b = dt_bilateral_init_cl(devid, width, height, sigma_s, sigma_r); if(!b) goto error; err = dt_bilateral_splat_cl(b, dev_in); if (err != CL_SUCCESS) goto error; err = dt_bilateral_blur_cl(b); if (err != CL_SUCCESS) goto error; err = dt_bilateral_slice_cl(b, dev_in, dev_out, detail); if (err != CL_SUCCESS) goto error; dt_bilateral_free_cl(b); b = NULL; // make sure we don't clean it up twice } dev_m = dt_opencl_copy_host_to_device(devid, d->table, 256, 256, sizeof(float)); if(dev_m == NULL) goto error; dev_coeffs = dt_opencl_copy_host_to_device_constant(devid, sizeof(float)*3, d->unbounded_coeffs); if(dev_coeffs == NULL) goto error; sizes[0] = ROUNDUPWD(width); sizes[1] = ROUNDUPWD(height); sizes[2] = 1; dt_opencl_set_kernel_arg(devid, gd->kernel_lowpass_mix, 0, sizeof(cl_mem), (void *)&dev_out); dt_opencl_set_kernel_arg(devid, gd->kernel_lowpass_mix, 1, sizeof(cl_mem), (void *)&dev_out); dt_opencl_set_kernel_arg(devid, gd->kernel_lowpass_mix, 2, sizeof(int), (void *)&width); dt_opencl_set_kernel_arg(devid, gd->kernel_lowpass_mix, 3, sizeof(int), (void *)&height); dt_opencl_set_kernel_arg(devid, gd->kernel_lowpass_mix, 4, sizeof(float), (void *)&saturation); dt_opencl_set_kernel_arg(devid, gd->kernel_lowpass_mix, 5, sizeof(cl_mem), (void *)&dev_m); dt_opencl_set_kernel_arg(devid, gd->kernel_lowpass_mix, 6, sizeof(cl_mem), (void *)&dev_coeffs); err = dt_opencl_enqueue_kernel_2d(devid, gd->kernel_lowpass_mix, sizes); if(err != CL_SUCCESS) goto error; if (dev_coeffs != NULL) dt_opencl_release_mem_object(dev_coeffs); if (dev_m != NULL) dt_opencl_release_mem_object(dev_m); return TRUE; error: if (g) dt_gaussian_free_cl(g); if (b) dt_bilateral_free_cl(b); if (dev_coeffs != NULL) dt_opencl_release_mem_object(dev_coeffs); if (dev_m != NULL) dt_opencl_release_mem_object(dev_m); dt_print(DT_DEBUG_OPENCL, "[opencl_lowpass] couldn't enqueue kernel! %d\n", err); return FALSE; }