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; }
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 *const roi_in, const dt_iop_roi_t *const 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_out); 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_out); 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_out, 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; dt_opencl_release_mem_object(dev_tmp); return TRUE; error: 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_graduatednd_data_t *data = (dt_iop_graduatednd_data_t *)piece->data; dt_iop_graduatednd_global_data_t *gd = (dt_iop_graduatednd_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 ix= (roi_in->x); const int iy= (roi_in->y); const float iw=piece->buf_in.width*roi_out->scale; const float ih=piece->buf_in.height*roi_out->scale; const float hw=iw/2.0; const float hh=ih/2.0; const float hw_inv=1.0/hw; const float hh_inv=1.0/hh; const float v=(-data->rotation/180)*M_PI; const float sinv=sin(v); const float cosv=cos(v); const float filter_radie=sqrt((hh*hh)+(hw*hw))/hh; const float offset=data->offset/100.0*2; const float density=data->density; float color[4] = { 0.0f }; hsl2rgb(color,data->hue,data->saturation,0.5); if (density < 0) for ( int l=0; l<3; l++ ) color[l] = 1.0f - color[l]; #if 1 const float filter_compression = 1.0/filter_radie/(1.0-(0.5+(data->compression/100.0)*0.9/2.0))*0.5; #else const float compression = data->compression/100.0f; const float t = 1.0f - .8f/(.8f + compression); const float c = 1.0f + 1000.0f*powf(4.0, compression); #endif const float length_base = (sinv * (-1.0+ix*hw_inv) - cosv * (-1.0+iy*hh_inv) - 1.0 + offset) * filter_compression; const float length_inc_y = -cosv * hh_inv * filter_compression; const float length_inc_x = sinv * hw_inv * filter_compression; size_t sizes[] = { ROUNDUPWD(width), ROUNDUPHT(height), 1}; int kernel = density > 0 ? gd->kernel_graduatedndp : gd->kernel_graduatedndm; dt_opencl_set_kernel_arg(devid, kernel, 0, sizeof(cl_mem), (void *)&dev_in); dt_opencl_set_kernel_arg(devid, kernel, 1, sizeof(cl_mem), (void *)&dev_out); dt_opencl_set_kernel_arg(devid, kernel, 2, sizeof(int), (void *)&width); dt_opencl_set_kernel_arg(devid, kernel, 3, sizeof(int), (void *)&height); dt_opencl_set_kernel_arg(devid, kernel, 4, 4*sizeof(float), (void *)color); dt_opencl_set_kernel_arg(devid, kernel, 5, sizeof(float), (void *)&density); dt_opencl_set_kernel_arg(devid, kernel, 6, sizeof(float), (void *)&length_base); dt_opencl_set_kernel_arg(devid, kernel, 7, sizeof(float), (void *)&length_inc_x); dt_opencl_set_kernel_arg(devid, kernel, 8, sizeof(float), (void *)&length_inc_y); err = dt_opencl_enqueue_kernel_2d(devid, kernel, sizes); if(err != CL_SUCCESS) goto error; return TRUE; error: dt_print(DT_DEBUG_OPENCL, "[opencl_graduatednd] couldn't enqueue kernel! %d\n", err); return FALSE; }