38 float *
const restrict interp = ctx->
interp;
39 const float *
const restrict mask = ctx->
mask;
40 const float *
const restrict depth = ctx->
depth;
46 float *
const restrict estimate = ctx->
estimate;
47 float *
const restrict valid = ctx->
valid;
48 float *
const restrict clip_depth = ctx->
clip_depth;
49 float *
const restrict clip0 = ctx->
clip0;
53 for(
int y = 0; y < region_h; y++)
54 for(
int x = 0;
x < region_w;
x++)
56 const size_t pixel_index = (size_t)(region->
ry0 + y) *
width + (region->
rx0 +
x);
57 const size_t src_offset = pixel_index * 4;
58 const size_t dst_offset = ((size_t)y * region_w +
x) * 4;
59 clip_depth[(size_t)y * region_w +
x] = depth[pixel_index];
60 for(
int k = 0;
k < 4;
k++)
62 estimate[dst_offset +
k] = interp[src_offset +
k];
63 clip0[dst_offset +
k] = interp[src_offset +
k];
64 valid[dst_offset +
k] = fmaxf(1.f - mask[src_offset +
k], 0.f);
73 for(
size_t i = 0;
i < region_pixels;
i++)
74 for(
int c = 0; c < 3; c++)
75 if(valid[
i * 4 + c] < 0.5f) estimate[
i * 4 + c] = fmaxf(estimate[
i * 4 + c], clip0[
i * 4 + c]);
83 float *
const restrict interp = ctx->
interp;
84 const float *
const restrict mask = ctx->
mask;
90 float *
const restrict estimate = ctx->
estimate;
91 float *
const restrict valid = ctx->
valid;
99 for(
int y = 0; y < region_h; y++)
101 for(
int x = 0;
x < region_w;
x++)
103 const size_t i = ((size_t)y * region_w +
x) * 4;
115 dt_aligned_pixel_t nsigma = { current[0] * noise_level, current[1] * noise_level, current[2] * noise_level,
116 current[3] * noise_level };
122 for(
int c = 0; c < 3; c++)
123 if(valid[
i + c] < 0.5f) estimate[
i + c] = fmaxf(current[c] + fabsf(
noise[c] - current[c]), 0.f);
135 for(
int y = 0; y < region_h; y++)
137 for(
int x = 0;
x < region_w;
x++)
139 const size_t src_offset = ((size_t)y * region_w +
x) * 4;
140 const size_t dst_offset = ((size_t)(region->
ry0 + y) *
width + (region->
rx0 +
x)) * 4;
143 for(
int c = 0; c < 3; c++)
144 if(mask[dst_offset + c] > 0.5f) interp[dst_offset + c] = fmaxf(estimate[src_offset + c], 0.f);
150 const float *
const restrict depth,
const int width,
const _hl_region_t *
const region,
152 const float noise_level)
154 const int region_w = region->
rx1 - region->
rx0 + 1;
155 const int region_h = region->
ry1 - region->
ry0 + 1;
156 if(region_w < 2 || region_h < 2)
return;
157 const size_t region_pixels = (size_t)region_w * region_h;
160 if(region_pixels > (
size_t)64 * 1024 * 1024)
return;
162 float *
const restrict estimate
164 float *
const restrict prev_scale
166 float *
const restrict valid
168 float *
const restrict blur_in
170 float *
const restrict plane1
172 float *
const restrict plane2
174 float *
const restrict plane3
176 float *
const restrict valid_variance
178 float *
const restrict guide_score
180 float *
const restrict clip_depth
182 float *
const restrict clip0
184 if(!estimate || !prev_scale || !valid || !blur_in || !plane1 || !plane2 || !plane3 || !valid_variance
185 || !guide_score || !clip_depth || !clip0)
201 const int extent =
MAX(region->
x1 - region->
x0, region->
y1 - region->
y0) + 1;
202 const float epsilon = 1e-6f;
203 const int max_cg_iter = CLAMP(2 * extent, 200, 2000);
211 float *
const restrict solver_field
213 float *
const restrict fill_planes
216 float *
const restrict lum_accum
218 float *
const restrict reaction_weight
220 float *
const restrict flat_target
235 .region_w = region_w,
236 .region_h = region_h,
237 .region_pixels = region_pixels,
240 .max_cg_iter = max_cg_iter,
241 .solid_color = solid_color,
242 .noise_level = noise_level,
243 .estimate = estimate,
244 .prev_scale = prev_scale,
250 .valid_variance = valid_variance,
251 .guide_score = guide_score,
252 .clip_depth = clip_depth,
255 .solver_field = solver_field,
256 .fill_planes = fill_planes,
257 .dome_lum = dome_lum,
258 .lum_accum = lum_accum,
259 .reaction_weight = reaction_weight,
260 .flat_target = flat_target,
261 .cg_residual = cg_residual,
263 .cg_operator = cg_operator,
270 if(hole && solver_field && fill_planes && dome_lum && lum_accum && reaction_weight && flat_target && cg_residual
271 && cg_dir && cg_operator && cg_tmp1 && cg_tmp2)
316#if defined(HAVE_OPENCL) && DT_HL_COEFF_FIELD && DT_HL_SPARSE_SOLVE && (DT_HL_ANISO_SOLVER == 2)
331cl_int _region_cpu_offload_cl(
const int devid,
void *gd_void, cl_mem interp, cl_mem mask, cl_mem depth,
333 const float solid_color,
const int max_iter,
const float noise_level)
336 const int region_w = region->
rx1 - region->
rx0 + 1;
337 const int region_h = region->
ry1 - region->
ry0 + 1;
338 if(region_w < 2 || region_h < 2)
return CL_SUCCESS;
339 const size_t region_pixels = (size_t)region_w * region_h;
360 if(cl_err != CL_SUCCESS)
goto out;
364 if(cl_err != CL_SUCCESS)
goto out;
367 float *
const hw_interp = host;
368 const float *
const hw_mask = host + region_pixels * 4;
369 const float *
const hw_depth = host + region_pixels * 8;
372 translated_region.
x0 -= region->
rx0;
373 translated_region.
x1 -= region->
rx0;
374 translated_region.
y0 -= region->
ry0;
375 translated_region.
y1 -= region->
ry0;
376 translated_region.
rx1 -= region->
rx0;
377 translated_region.
ry1 -= region->
ry0;
378 translated_region.
rx0 = 0;
379 translated_region.
ry0 = 0;
381 _region_guided_filter(hw_interp, hw_mask, hw_depth, region_w, &translated_region, pipe, solid_color, max_iter,
386 if(cl_err != CL_SUCCESS)
goto out;
406cl_int _region_guided_filter_cl(
const int devid,
void *gd_void, cl_mem interp, cl_mem mask, cl_mem depth,
408 const float solid_color)
411 const int region_w = region->
rx1 - region->
rx0 + 1;
412 const int region_h = region->
ry1 - region->
ry0 + 1;
413 if(region_w < 2 || region_h < 2)
return CL_SUCCESS;
414 const size_t region_pixels = (size_t)region_w * region_h;
415 if(region_pixels > (
size_t)64 * 1024 * 1024)
return CL_SUCCESS;
429 if(!estimate || !valid || !clip0 || !model_quality || !clip_depth || !lsb0 || !partials)
goto out;
449 if(cl_err != CL_SUCCESS)
goto out;
453 const float cf_sigma = CLAMP(region->
radius / 6.f, 8.f, 64.f);
454 const float cf_fmin = 0.05f;
456 float channel_means[3] = { 0.f, 0.f, 0.f };
457 int cdeep, ds_shared;
459 const int local_size = 64, n_groups = 256;
460 const int pixel_count = (int)region_pixels;
462 size_t sizes[3] = { (size_t)n_groups * local_size, 1, 1 };
463 size_t local[3] = { local_size, 1, 1 };
470 if(cl_err != CL_SUCCESS)
goto out;
472 float partials_host[8 * 256];
475 if(cl_err != CL_SUCCESS)
goto out;
476 double lsum = 0.0, lcnt = 0.0, clip_count_r = 0.0, clip_count_g = 0.0, clip_count_b = 0.0;
477 double msum[3] = { 0.0, 0.0, 0.0 };
478 for(
int group = 0; group < n_groups; group++)
480 lsum += (
double)partials_host[8 * group + 0];
481 lcnt += (
double)partials_host[8 * group + 1];
482 clip_count_r += (
double)partials_host[8 * group + 2];
483 clip_count_g += (
double)partials_host[8 * group + 3];
484 clip_count_b += (
double)partials_host[8 * group + 4];
485 msum[0] += (
double)partials_host[8 * group + 5];
486 msum[1] += (
double)partials_host[8 * group + 6];
487 msum[2] += (
double)partials_host[8 * group + 7];
494 const float cf_lref = (float)(lsum / lcnt);
495 cf_binv = (cf_lref > 1e-9f) ? 1.f / (0.35f * cf_lref) : 0.f;
496 cdeep = (clip_count_r >= clip_count_g && clip_count_r >= clip_count_b)
498 : ((clip_count_g >= clip_count_b) ? 1 : 2);
502 const double valid_count_r = (
double)region_pixels - clip_count_r,
503 valid_count_g = (
double)region_pixels - clip_count_g,
504 valid_count_b = (
double)region_pixels - clip_count_b;
505 channel_means[0] = valid_count_r > 0.5 ? (float)(msum[0] / valid_count_r) : 0.f;
506 channel_means[1] = valid_count_g > 0.5 ? (float)(msum[1] / valid_count_g) : 0.f;
507 channel_means[2] = valid_count_b > 0.5 ? (float)(msum[2] / valid_count_b) : 0.f;
522 const int pixel_count = (int)region_pixels;
523 size_t work_size_1d[3] = {
ROUNDUPDWD(pixel_count, devid), 1, 1 };
529 if(cl_err != CL_SUCCESS)
goto out;
533 cl_err =
_cf_stage_cl(devid, gd_void, estimate, valid, model_quality, lsb0, steer, channel_means, cf_gaussian,
534 region_w, region_h, cf_sigma, cf_fmin, cf_binv, cdeep);
536 if(cl_err != CL_SUCCESS)
goto out;
537 cl_err =
_hf_stage_cl(devid, gd_void, estimate, valid, model_quality, lsb0, steer, cf_gaussian, region_w,
538 region_h, cf_sigma, cf_fmin, cf_binv);
540 if(cl_err != CL_SUCCESS)
goto out;
547 const int local_size = 64, n_groups = 256;
548 const int pixel_count = (int)region_pixels;
550 size_t sizes[3] = { (size_t)n_groups * local_size, 1, 1 };
551 size_t local[3] = { local_size, 1, 1 };
560 if(cl_err != CL_SUCCESS)
goto out;
561 float partials_host[256];
564 if(cl_err != CL_SUCCESS)
goto out;
565 for(
int group = 0; group < n_groups; group++)
566 if(partials_host[group] > 0.f) need_self = 1;
571 cl_err = _selfdome_stage_cl(devid, gd_void, estimate, valid, model_quality, clip0, clip_depth, region_w,
572 region_h, cf_sigma, region->
radius, ds_shared, pipe);
573 if(cl_err != CL_SUCCESS)
goto out;
584 if(cl_err != CL_SUCCESS)
goto out;
589 const int extent =
MAX(region->
x1 - region->
x0, region->
y1 - region->
y0) + 1;
590 cl_err = _joint_core_stage_cl(devid, gd_void, estimate, valid, clip0, region_w, region_h, solid_color,
591 region->
radius, extent, pipe);
594 if(cl_err != CL_SUCCESS)
goto out;
596 cl_err = _aniso_stage_cl(devid, gd_void, estimate, valid, clip0, region_w, region_h, region->
radius, pipe);
598 if(cl_err != CL_SUCCESS)
goto out;
dt_gaussian_cl_t * _region_blur_handle(const int devid, const int region_w, const int region_h, const float sigma)
__DT_CLONE_TARGETS__ void _aniso_chroma(_hl_region_ctx_t *const ctx)
cl_int _cf_stage_cl(const int devid, void *gd_void, cl_mem estimate, cl_mem valid, cl_mem model_quality, cl_mem luminance, cl_mem steer, const float *const restrict channel_means, dt_gaussian_cl_t *gaussian, const int region_w, const int region_h, const float cf_sigma, const float cf_fmin, const float cf_binv, const int cdeep)
__DT_CLONE_TARGETS__ void _cf_reconstruct(_hl_region_ctx_t *const ctx)
cl_int _hf_stage_cl(const int devid, void *gd_void, cl_mem estimate, cl_mem valid, cl_mem model_quality, cl_mem luminance, cl_mem steer, dt_gaussian_cl_t *gaussian, const int region_w, const int region_h, const float cf_sigma, const float cf_fmin, const float cf_binv)
const dt_colormatrix_t dt_aligned_pixel_t out
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
__DT_CLONE_TARGETS__ void _joint_core(_hl_region_ctx_t *const ctx)
__DT_CLONE_TARGETS__ void _selfdome(_hl_region_ctx_t *const ctx)
#define dt_pixelpipe_cache_alloc_align(size, pipe)
#define dt_pixelpipe_cache_free_align(mem)
#define dt_pixelpipe_cache_alloc_align_float(pixels, pipe)
#define __DT_CLONE_TARGETS__
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
static float4 dt_noise_generator_simd(const dt_noise_distribution_t distribution, const float4 mu, const float4 param, uint state[4])
static unsigned int splitmix32(const unsigned long seed)
static float xoshiro128plus(uint state[4])
void dt_gaussian_free_cl(dt_gaussian_cl_t *g)
static float kernel(const float *x, const float *y)
float *const restrict const size_t k
float dt_aligned_pixel_t[4]
int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
void * dt_opencl_alloc_device_buffer(const int devid, const size_t size)
int dt_opencl_write_buffer_to_device(const int devid, void *host, void *device, const size_t offset, const size_t size, const int blocking)
int dt_opencl_read_buffer_from_device(const int devid, void *host, void *device, const size_t offset, const size_t size, const int blocking)
int dt_opencl_set_kernel_arg(const int dev, const int kernel, const int num, const size_t size, const void *arg)
gboolean dt_opencl_finish(const int devid)
int dt_opencl_enqueue_kernel_2d_with_local(const int dev, const int kernel, const size_t *sizes, const size_t *local)
void dt_opencl_release_mem_object(cl_mem mem)
#define DT_OPENCL_DEFAULT_ERROR
static __DT_CLONE_TARGETS__ void _region_composite(_hl_region_ctx_t *const ctx)
static __DT_CLONE_TARGETS__ void _region_gather(_hl_region_ctx_t *const ctx)
void _region_guided_filter(float *const restrict interp, const float *const restrict mask, const float *const restrict depth, const int width, const _hl_region_t *const region, const dt_dev_pixelpipe_t *pipe, const float solid_color, const int max_iter, const float noise_level)
const float uint32_t state[4]
const float const int flip
#define DT_HL_DOME_NMAX_SPARSE
const _hl_region_t * region
int kernel_hl_window_unpack
int kernel_hl_region_gather
int kernel_hl_region_stats
int kernel_hl_window_pack
int kernel_hl_region_scatter
typedef double((*spd)(unsigned long int wavelength, double TempK))