291 const uint8_t *const restrict hole, const
int region_w, const
int region_h,
292 const
int base_ds, const
float *const restrict steer,
296 const int downsample = CLAMP(base_ds, 1, 8);
297 const int base_w = (region_w + downsample - 1) / downsample;
298 const int base_h = (region_h + downsample - 1) / downsample;
299 const size_t cell_count = (size_t)base_w * base_h;
302 uint8_t *
const restrict base_anchor
305 float *
const restrict level_buffers
307 uint8_t *
const restrict level_anchor
313 const int steered = (steer && aniso_aux) ? 1 : 0;
315 if(!base_vals || !base_anchor || !level_buffers || !level_anchor || (steer && !aniso_aux))
318 for(
int plane = 0; plane < n_planes; plane++)
320 float *
const restrict plane_vals = vals[plane];
321 double anchor_sum = 0.0;
322 size_t anchor_count = 0;
323 for(
size_t i = 0;
i < (size_t)region_w * region_h;
i++)
326 anchor_sum += plane_vals[
i];
330 const float anchor_mean = anchor_count ? (float)(anchor_sum / (
double)anchor_count) : 0.f;
332 for(
size_t i = 0;
i < (size_t)region_w * region_h;
i++)
333 if(hole[
i]) plane_vals[
i] = anchor_mean;
345 float *
const restrict base_steer = steered ? aniso_aux + 5 * cell_count : NULL;
349 for(
int base_y = 0; base_y < base_h; base_y++)
350 for(
int base_x = 0; base_x < base_w; base_x++)
354 for(
int y = base_y * downsample; y <
MIN((base_y + 1) * downsample, region_h); y++)
355 for(
int x = base_x * downsample;
x <
MIN((base_x + 1) * downsample, region_w);
x++)
357 accum += steer[(size_t)y * region_w +
x];
360 base_steer[(size_t)base_y * base_w + base_x] = (
float)(accum / n_total);
366 for(
int base_y = 0; base_y < base_h; base_y++)
367 for(
int base_x = 0; base_x < base_w; base_x++)
373 for(
int y = base_y * downsample; y <
MIN((base_y + 1) * downsample, region_h); y++)
374 for(
int x = base_x * downsample;
x <
MIN((base_x + 1) * downsample, region_w);
x++)
376 const size_t i = (size_t)y * region_w +
x;
381 for(
int plane = 0; plane < n_planes; plane++) accum[plane] += vals[plane][
i];
386 const size_t cell_index = (size_t)base_y * base_w + base_x;
387 for(
int plane = 0; plane < n_planes; plane++)
388 base_vals[plane * cell_count + cell_index] = n_anchor ? (
float)(accum[plane] / n_anchor) : 0.f;
389 base_anchor[cell_index] = (2 * n_anchor > n_total);
401 while((
MAX(base_w, base_h) >> n_levels) > 8 && n_levels < 12) n_levels++;
403 float *
const restrict field = level_buffers + 0 * cell_count;
404 float *
const restrict tmp = level_buffers + (size_t)n_planes * cell_count;
405 float *
const restrict level_vals
406 = level_buffers + 2 * (size_t)n_planes * cell_count;
408 int prev_level_w = 0;
409 int prev_level_h = 0;
411 for(
int level = n_levels - 1; level >= 0; level--)
413 const int step = 1 << level;
414 const int level_w = (base_w + step - 1) / step;
415 const int level_h = (base_h + step - 1) / step;
419 for(
int level_y = 0; level_y < level_h; level_y++)
420 for(
int level_x = 0; level_x < level_w; level_x++)
426 for(
int y = level_y * step; y <
MIN((level_y + 1) * step, base_h); y++)
427 for(
int x = level_x * step;
x <
MIN((level_x + 1) * step, base_w);
x++)
429 const size_t i = (size_t)y * base_w +
x;
434 for(
int plane = 0; plane < n_planes; plane++) accum[plane] += base_vals[plane * cell_count +
i];
439 const size_t cell_index = (size_t)level_y * level_w + level_x;
440 for(
int plane = 0; plane < n_planes; plane++)
441 level_vals[plane * cell_count + cell_index] = n_anchor ? (
float)(accum[plane] / n_anchor) : 0.f;
442 level_anchor[cell_index] = (2 * n_anchor > n_total);
446 float *
const restrict level_steer = steered ? aniso_aux + 0 * cell_count : NULL;
447 float *
const restrict tensor_xx = steered ? aniso_aux + 1 * cell_count : NULL;
448 float *
const restrict tensor_xy = steered ? aniso_aux + 2 * cell_count : NULL;
449 float *
const restrict tensor_yy = steered ? aniso_aux + 3 * cell_count : NULL;
454 for(
int level_y = 0; level_y < level_h; level_y++)
455 for(
int level_x = 0; level_x < level_w; level_x++)
457 double steer_sum = 0.0;
459 for(
int y = level_y * step; y <
MIN((level_y + 1) * step, base_h); y++)
460 for(
int x = level_x * step;
x <
MIN((level_x + 1) * step, base_w);
x++)
462 steer_sum += base_steer[(size_t)y * base_w +
x];
465 level_steer[(size_t)level_y * level_w + level_x] = (
float)(steer_sum / n_total);
469 _cf_adaptive_tensor(level_steer, tensor_xx, tensor_xy, tensor_yy, aniso_aux + 4 * cell_count,
470 aniso_aux + 6 * cell_count, level_w, level_h,
DT_HL_CF_K);
476 float *
const restrict edge_weights = aniso_aux + 7 * cell_count;
477 float *
const restrict edge_weight_sum = aniso_aux + 15 * cell_count;
479 for(
int level_y = 0; level_y < level_h; level_y++)
480 for(
int level_x = 0; level_x < level_w; level_x++)
482 static const int neighbour_dy[8] = { 0, 0, -1, 1, -1, 1, 1, -1 };
483 static const int neighbour_dx[8] = { -1, 1, 0, 0, -1, 1, -1, 1 };
484 const size_t i = (size_t)level_y * level_w + level_x;
485 float weight_sum = 0.f;
486 for(
int k = 0;
k < 8;
k++)
488 const int neighbour_y = CLAMP(level_y + neighbour_dy[
k], 0, level_h - 1);
489 const int neighbour_x = CLAMP(level_x + neighbour_dx[
k], 0, level_w - 1);
490 const size_t cell_index = (size_t)neighbour_y * level_w + neighbour_x;
493 =
_aniso_edge_w(tensor_xx, tensor_xy, tensor_yy,
i, cell_index, neighbour_dx[
k], neighbour_dy[
k]);
497 edge_weight_sum[
i] = weight_sum;
501 if(level == n_levels - 1)
506 size_t anchor_count = 0;
507 for(
size_t i = 0;
i < (size_t)level_w * level_h;
i++)
510 for(
int plane = 0; plane < n_planes; plane++) anchor_sum[plane] += level_vals[plane * cell_count +
i];
515 for(
int plane = 0; plane < n_planes; plane++)
516 anchor_mean[plane] = anchor_count ? (
float)(anchor_sum[plane] / (
double)anchor_count) : 0.f;
518 for(
size_t i = 0;
i < (size_t)level_w * level_h;
i++)
519 for(
int plane = 0; plane < n_planes; plane++)
520 tmp[plane * cell_count +
i] = level_anchor[
i] ? level_vals[plane * cell_count +
i] : anchor_mean[plane];
526 for(
int level_y = 0; level_y < level_h; level_y++)
527 for(
int level_x = 0; level_x < level_w; level_x++)
529 const size_t i = (size_t)level_y * level_w + level_x;
533 for(
int plane = 0; plane < n_planes; plane++)
534 tmp[plane * cell_count +
i] = level_vals[plane * cell_count +
i];
538 const float grid_x = ((float)level_x + 0.5f) * 0.5f - 0.5f;
539 const float grid_y = ((float)level_y + 0.5f) * 0.5f - 0.5f;
540 const int x_lo = CLAMP((
int)floorf(grid_x), 0, prev_level_w - 1);
541 const int y_lo = CLAMP((
int)floorf(grid_y), 0, prev_level_h - 1);
542 const int x_hi =
MIN(x_lo + 1, prev_level_w - 1);
543 const int y_hi =
MIN(y_lo + 1, prev_level_h - 1);
544 const float frac_x = CLAMP(grid_x - x_lo, 0.f, 1.f);
545 const float frac_y = CLAMP(grid_y - y_lo, 0.f, 1.f);
546 for(
int plane = 0; plane < n_planes; plane++)
548 const float *
const plane_field = field + plane * cell_count;
549 const float interp_top = plane_field[(size_t)y_lo * prev_level_w + x_lo] * (1.f - frac_x)
550 + plane_field[(size_t)y_lo * prev_level_w + x_hi] * frac_x;
551 const float interp_bottom = plane_field[(size_t)y_hi * prev_level_w + x_lo] * (1.f - frac_x)
552 + plane_field[(size_t)y_hi * prev_level_w + x_hi] * frac_x;
553 tmp[plane * cell_count +
i] = interp_top * (1.f - frac_y) + interp_bottom * frac_y;
558 for(
int plane = 0; plane < n_planes; plane++)
559 memcpy(field + plane * cell_count, tmp + plane * cell_count, (
size_t)level_w * level_h *
sizeof(float));
564 const float *
const restrict edge_weights = steered ? aniso_aux + 7 * cell_count : NULL;
565 const float *
const restrict edge_weight_sum = steered ? aniso_aux + 15 * cell_count : NULL;
569 _cf_fill_relax_1(field, tmp, level_anchor, edge_weights, edge_weight_sum, level_w, level_h, cell_count,
573 _cf_fill_relax_2(field, tmp, level_anchor, edge_weights, edge_weight_sum, level_w, level_h, cell_count,
577 _cf_fill_relax_3(field, tmp, level_anchor, edge_weights, edge_weight_sum, level_w, level_h, cell_count,
581 _cf_fill_relax_4(field, tmp, level_anchor, edge_weights, edge_weight_sum, level_w, level_h, cell_count,
587 prev_level_w = level_w;
588 prev_level_h = level_h;
594 for(
int y = 0; y < region_h; y++)
595 for(
int x = 0;
x < region_w;
x++)
597 const size_t i = (size_t)y * region_w +
x;
599 if(!hole[
i])
continue;
601 const float grid_x = ((float)
x + 0.5f) / downsample - 0.5f;
602 const float grid_y = ((float)y + 0.5f) / downsample - 0.5f;
603 const int x_lo = CLAMP((
int)floorf(grid_x), 0, base_w - 1);
604 const int y_lo = CLAMP((
int)floorf(grid_y), 0, base_h - 1);
605 const int x_hi =
MIN(x_lo + 1, base_w - 1);
606 const int y_hi =
MIN(y_lo + 1, base_h - 1);
607 const float frac_x = CLAMP(grid_x - x_lo, 0.f, 1.f);
608 const float frac_y = CLAMP(grid_y - y_lo, 0.f, 1.f);
609 for(
int plane = 0; plane < n_planes; plane++)
611 const float *
const plane_field = field + plane * cell_count;
612 const float interp_top = plane_field[(size_t)y_lo * base_w + x_lo] * (1.f - frac_x)
613 + plane_field[(size_t)y_lo * base_w + x_hi] * frac_x;
614 const float interp_bottom = plane_field[(size_t)y_hi * base_w + x_lo] * (1.f - frac_x)
615 + plane_field[(size_t)y_hi * base_w + x_hi] * frac_x;
616 vals[plane][
i] = interp_top * (1.f - frac_y) + interp_bottom * frac_y;
643 float *
const restrict estimate = ctx->
estimate;
644 float *
const restrict prev_scale = ctx->
prev_scale;
645 float *
const restrict valid = ctx->
valid;
646 float *
const restrict blur_in = ctx->
blur_in;
647 float *
const restrict plane1 = ctx->
plane1;
648 float *
const restrict plane2 = ctx->
plane2;
649 float *
const restrict plane3 = ctx->
plane3;
651 float *
const restrict guide_score = ctx->
guide_score;
652 float *
const restrict clip_depth = ctx->
clip_depth;
653 float *
const restrict clip0 = ctx->
clip0;
654 uint8_t *
const restrict hole = ctx->
hole;
656 float *
const restrict fill_planes = ctx->
fill_planes;
657 float *
const restrict dome_lum = ctx->
dome_lum;
658 float *
const restrict lum_accum = ctx->
lum_accum;
660 float *
const restrict flat_target = ctx->
flat_target;
663 = CLAMP(region->
radius / 6.f, 8.f, 64.f);
665 const float cf_fmin = 0.05f;
670 float *
const restrict cf_guide = ctx->
cg_tmp1;
671 float *
const restrict cf_step_x = ctx->
cg_tmp2;
672 float *
const restrict cf_step_y = ctx->
cg_residual;
676 for(
size_t i = 0;
i < region_pixels;
i++)
677 lum_accum[
i] = estimate[
i * 4 + 0] + estimate[
i * 4 + 1] + estimate[
i * 4 + 2];
681 HL_PFOR(reduction(+ : laccum, lcnt))
682 for(
size_t i = 0;
i < region_pixels;
i++)
683 if(valid[
i * 4 + 0] < 0.5f || valid[
i * 4 + 1] < 0.5f || valid[
i * 4 + 2] < 0.5f)
685 laccum += lum_accum[
i];
689 const float cf_lref = lcnt ? (float)(laccum / (
double)lcnt) : 0.f;
699 for(
size_t i = 0;
i < region_pixels;
i++)
703 for(
int c = 0; c < 3; c++)
704 if(valid[
i * 4 + c] >= 0.5f)
706 accum += estimate[
i * 4 + c];
709 steer[
i] = n_valid ? accum / n_valid : lum_accum[
i] / 3.f;
719 double maccum[3] = { 0.0, 0.0, 0.0 };
720 size_t mcnt[3] = { 0, 0, 0 };
721 HL_PFOR(reduction(+ : maccum[:3], mcnt[:3]))
722 for(
size_t i = 0;
i < region_pixels;
i++)
723 for(
int c = 0; c < 3; c++)
724 if(valid[
i * 4 + c] >= 0.5f)
726 maccum[c] += estimate[
i * 4 + c];
729 const float channel_means[3]
730 = { mcnt[0] ? (float)(maccum[0] / mcnt[0]) : 0.f, mcnt[1] ? (float)(maccum[1] / mcnt[1]) : 0.f,
731 mcnt[2] ? (float)(maccum[2] / mcnt[2]) : 0.f };
738 const float cf_binv = (cf_lref > 1e-9f) ? 1.f / (0.35f * cf_lref) : 0.f;
744 float *
const restrict cf_guide_raw = ctx->
cg_dir;
746 for(
size_t i = 0;
i < region_pixels;
i++) cf_guide_raw[
i] = lum_accum[
i];
748 {
const char *o = getenv(
"HL_CF_GUIDE");
if(o) cf_guide_smooth = (float)atof(o); }
749 if(cf_guide_smooth > 0.f)
750 _knee_blur(cf_guide_raw, cf_guide, region_w, region_h, cf_guide_smooth);
752 memcpy(cf_guide, cf_guide_raw, region_pixels *
sizeof(
float));
754 {
const char *o = getenv(
"HL_CF_RANGE");
if(o) cf_sigma_r = (float)atof(o) * fmaxf(cf_lref, 1e-9f); }
757 uint8_t *
const restrict hole2
764 for(
size_t i = 0;
i < region_pixels;
i++)
765 for(
int c = 0; c < 4; c++) guide_score[
i * 4 + c] = 0.f;
775 for(
size_t i = 0;
i < region_pixels;
i++)
777 const float lum_weight = (cf_binv > 0.f) ? sqf(fminf(lum_accum[
i] * cf_binv, 1.f)) : 1.f;
779 = (valid[
i * 4 + 0] >= 0.5f && valid[
i * 4 + 1] >= 0.5f && valid[
i * 4 + 2] >= 0.5f) ? lum_weight : 0.f;
781 blur_in[
i * 4 + 1] =
weight * (estimate[
i * 4 + 0] - channel_means[0]);
782 blur_in[
i * 4 + 2] =
weight * (estimate[
i * 4 + 1] - channel_means[1]);
783 blur_in[
i * 4 + 3] =
weight * (estimate[
i * 4 + 2] - channel_means[2]);
786 _region_edge_blur(blur_in, prev_scale, cf_guide, cf_step_x, cf_step_y, region_w, region_h,
787 cf_sigma, cf_sigma_r);
790 for(
size_t i = 0;
i < region_pixels;
i++)
792 const float lum_weight = (cf_binv > 0.f) ? sqf(fminf(lum_accum[
i] * cf_binv, 1.f)) : 1.f;
794 = (valid[
i * 4 + 0] >= 0.5f && valid[
i * 4 + 1] >= 0.5f && valid[
i * 4 + 2] >= 0.5f) ? lum_weight : 0.f;
797 = estimate[
i * 4 + 0] - channel_means[0];
798 const float val_g = estimate[
i * 4 + 1] - channel_means[1];
799 const float val_b = estimate[
i * 4 + 2] - channel_means[2];
800 blur_in[
i * 4 + 0] =
weight * val_r * val_r;
801 blur_in[
i * 4 + 1] =
weight * val_g * val_g;
802 blur_in[
i * 4 + 2] =
weight * val_b * val_b;
803 blur_in[
i * 4 + 3] =
weight * val_r * val_g;
806 _region_edge_blur(blur_in, plane1, cf_guide, cf_step_x, cf_step_y, region_w, region_h,
807 cf_sigma, cf_sigma_r);
810 for(
size_t i = 0;
i < region_pixels;
i++)
812 const float lum_weight = (cf_binv > 0.f) ? sqf(fminf(lum_accum[
i] * cf_binv, 1.f)) : 1.f;
814 = (valid[
i * 4 + 0] >= 0.5f && valid[
i * 4 + 1] >= 0.5f && valid[
i * 4 + 2] >= 0.5f) ? lum_weight : 0.f;
816 blur_in[
i * 4 + 0] =
weight * (estimate[
i * 4 + 0] - channel_means[0])
817 * (estimate[
i * 4 + 2] - channel_means[2]);
818 blur_in[
i * 4 + 1] =
weight * (estimate[
i * 4 + 1] - channel_means[1])
819 * (estimate[
i * 4 + 2] - channel_means[2]);
820 blur_in[
i * 4 + 2] = (valid[
i * 4 + 0] >= 0.5f && valid[
i * 4 + 1] >= 0.5f && valid[
i * 4 + 2] >= 0.5f)
823 blur_in[
i * 4 + 3] = 0.f;
826 _region_edge_blur(blur_in, plane3, cf_guide, cf_step_x, cf_step_y, region_w, region_h,
827 cf_sigma, cf_sigma_r);
833#define CF_M2(nb_index, coef_a, coef_b) \
834 (((coef_a) == (coef_b)) ? plane1[(nb_index) * 4 + (coef_a)] \
835 : ((2 + (coef_a) + (coef_b)) < 4 ? plane1[(nb_index) * 4 + 2 + (coef_a) + (coef_b)] \
836 : plane3[(nb_index) * 4 + (coef_a) + (coef_b) - 2]))
843 size_t nclip_c[3] = { 0, 0, 0 };
844 for(
size_t i = 0;
i < region_pixels;
i++)
845 for(
int c = 0; c < 3; c++)
846 if(valid[
i * 4 + c] < 0.5f) nclip_c[c]++;
850 = (nclip_c[0] >= nclip_c[1] && nclip_c[0] >= nclip_c[2]) ? 0 : ((nclip_c[1] >= nclip_c[2]) ? 1 : 2);
851 int deep_stashed = 0;
854 for(
int c = 0; c < 3; c++)
857 const int guide1 = (c == 0) ? 1 : 0;
858 const int guide2 = (c == 2) ? 1 : 2;
861 HL_PFOR(reduction(+ : ntarget))
862 for(
size_t i = 0;
i < region_pixels;
i++)
863 if(valid[
i * 4 + c] < 0.5f && (valid[
i * 4 + guide1] >= 0.5f || valid[
i * 4 + guide2] >= 0.5f)) ntarget++;
865 if(ntarget == 0)
continue;
877 for(
size_t i = 0;
i < region_pixels;
i++)
879 const float norm = fmaxf(prev_scale[
i * 4 + 0], 1e-9f);
880 const float inv_det = 1.f / norm;
881 const float mean1 = prev_scale[
i * 4 + 1 + guide1] * inv_det;
882 const float mean2 = prev_scale[
i * 4 + 1 + guide2] * inv_det;
883 const float mean_target = prev_scale[
i * 4 + 1 + c] * inv_det;
885 = fmaxf(
CF_M2(
i, guide1, guide1) * inv_det - mean1 * mean1, 0.f);
886 const float var22 = fmaxf(
CF_M2(
i, guide2, guide2) * inv_det - mean2 * mean2, 0.f);
887 const float var12 =
CF_M2(
i, guide1, guide2) * inv_det - mean1 * mean2;
888 const float cov_tg1 =
CF_M2(
i, c, guide1) * inv_det - mean_target * mean1;
889 const float cov_tg2 =
CF_M2(
i, c, guide2) * inv_det - mean_target * mean2;
891 const float var_target
892 = fmaxf(
CF_M2(
i, c, c) * inv_det - mean_target * mean_target, 0.f);
895 const float lambda = 1e-3f * 0.5f * (var11 + var22) + 1e-12f;
896 const float determinant
897 = fmaxf((var11 + lambda) * (var22 + lambda) - var12 * var12, 1e-18f);
899 = ((var22 + lambda) * cov_tg1 - var12 * cov_tg2) / determinant;
901 = ((var11 + lambda) * cov_tg2 - var12 * cov_tg1) / determinant;
902 const float r_sq = CLAMP((slope_a * cov_tg1 + slope_b * cov_tg2) / (var_target + 1e-12f), 0.f,
905 valid_variance[
i * 4 + 0] = slope_a;
906 valid_variance[
i * 4 + 1] = slope_b;
908 valid_variance[
i * 4 + 2] = (mean_target + channel_means[c]) - slope_a * (mean1 + channel_means[guide1])
909 - slope_b * (mean2 + channel_means[guide2]);
910 valid_variance[
i * 4 + 3] = r_sq;
918 const int mass_ok = (plane3[
i * 4 + 2] > cf_fmin && prev_scale[
i * 4 + 0] > 0.25f * plane3[
i * 4 + 2]);
922 hole[
i] = !(mass_ok && valid[
i * 4 + c] >= 0.5f && r_sq > 0.25f && fabsf(slope_a) < 64.f
923 && fabsf(slope_b) < 64.f);
925 hole2[
i] = !(mass_ok && valid[
i * 4 + c] >= 0.5f);
934 for(
size_t i = 0;
i < region_pixels;
i++)
936 fill_planes[
i] = valid_variance[
i * 4 + 0];
937 fill_planes[region_pixels +
i] = valid_variance[
i * 4 + 1];
938 fill_planes[2 * region_pixels +
i] = valid_variance[
i * 4 + 2];
939 solver_field[
i] = valid_variance[
i * 4 + 3];
943 float *planes[3] = { fill_planes, fill_planes + region_pixels, fill_planes + 2 * region_pixels };
944 _cf_harmonic_fill_n((
float *
const restrict *)planes, 3, hole, region_w, region_h, (
int)(cf_sigma / 4.f),
948 _cf_harmonic_fill(solver_field, hole2 ? hole2 : hole, region_w, region_h, (int)(cf_sigma / 4.f), steer, pipe);
951 for(
size_t i = 0;
i < region_pixels;
i++)
953 valid_variance[
i * 4 + 0] = fill_planes[
i];
954 valid_variance[
i * 4 + 1] = fill_planes[region_pixels +
i];
955 valid_variance[
i * 4 + 2] = fill_planes[2 * region_pixels +
i];
956 valid_variance[
i * 4 + 3] = solver_field[
i];
968 for(
size_t i = 0;
i < region_pixels;
i++)
970 reaction_weight[
i] = valid_variance[
i * 4 + 0];
971 flat_target[
i] = valid_variance[
i * 4 + 1];
972 dome_lum[
i] = valid_variance[
i * 4 + 2];
973 guide_score[
i * 4 + 3] = valid_variance[
i * 4 + 3];
984 for(
size_t i = 0;
i < region_pixels;
i++)
985 if(valid[
i * 4 + c] < 0.5f && valid[
i * 4 + guide1] >= 0.5f && valid[
i * 4 + guide2] >= 0.5f)
988 estimate[
i * 4 + c] = valid_variance[
i * 4 + 0] * estimate[
i * 4 + guide1]
989 + valid_variance[
i * 4 + 1] * estimate[
i * 4 + guide2] + valid_variance[
i * 4 + 2];
990 guide_score[
i * 4 + c]
991 = CLAMP(valid_variance[
i * 4 + 3], 0.f, 1.f);
1002 HL_PFOR(reduction(+ : n2clip))
1003 for(
size_t i = 0;
i < region_pixels;
i++)
1005 const int n_valid = (valid[
i * 4 + 0] >= 0.5f) + (valid[
i * 4 + 1] >= 0.5f) + (valid[
i * 4 + 2] >= 0.5f);
1006 if(n_valid == 1) n2clip++;
1010 for(
int chan_a = 0; chan_a < 3; chan_a++)
1011 for(
int chan_b = chan_a + 1; chan_b < 3; chan_b++)
1016 for(
size_t i = 0;
i < region_pixels;
i++)
1018 const float lum_weight = (cf_binv > 0.f) ? sqf(fminf(lum_accum[
i] * cf_binv, 1.f)) : 1.f;
1019 const float weight = (valid[
i * 4 + chan_a] >= 0.5f && valid[
i * 4 + chan_b] >= 0.5f) ? lum_weight : 0.f;
1020 const float var_a = estimate[
i * 4 + chan_a] - channel_means[chan_a];
1021 const float var_b = estimate[
i * 4 + chan_b] - channel_means[chan_b];
1023 blur_in[
i * 4 + 1] =
weight * var_a;
1024 blur_in[
i * 4 + 2] =
weight * var_b;
1025 blur_in[
i * 4 + 3] =
weight * var_a * var_a;
1028 _region_blur(blur_in, plane2, region_w, region_h, cf_sigma);
1031 for(
size_t i = 0;
i < region_pixels;
i++)
1033 const float lum_weight = (cf_binv > 0.f) ? sqf(fminf(lum_accum[
i] * cf_binv, 1.f)) : 1.f;
1034 const float weight = (valid[
i * 4 + chan_a] >= 0.5f && valid[
i * 4 + chan_b] >= 0.5f) ? lum_weight : 0.f;
1035 const float var_a = estimate[
i * 4 + chan_a] - channel_means[chan_a];
1036 const float var_b = estimate[
i * 4 + chan_b] - channel_means[chan_b];
1037 blur_in[
i * 4 + 0] =
weight * var_b * var_b;
1038 blur_in[
i * 4 + 1] =
weight * var_a * var_b;
1039 blur_in[
i * 4 + 2] = (valid[
i * 4 + chan_a] >= 0.5f && valid[
i * 4 + chan_b] >= 0.5f) ? 1.f : 0.f;
1040 blur_in[
i * 4 + 3] = 0.f;
1043 _region_blur(blur_in, plane3, region_w, region_h, cf_sigma);
1046 for(
int orient = 0; orient < 2; orient++)
1048 const int target_chan = orient ? chan_b : chan_a;
1049 const int guide_chan = orient ? chan_a : chan_b;
1050 const int other_chan = 3 - chan_a - chan_b;
1053 HL_PFOR(reduction(+ : ntarget))
1054 for(
size_t i = 0;
i < region_pixels;
i++)
1055 if(valid[
i * 4 + target_chan] < 0.5f && valid[
i * 4 + guide_chan] >= 0.5f
1056 && valid[
i * 4 + other_chan] < 0.5f)
1059 if(ntarget == 0)
continue;
1062 for(
size_t i = 0;
i < region_pixels;
i++)
1064 const float norm = fmaxf(plane2[
i * 4 + 0], 1e-9f);
1065 const float inv_det = 1.f / norm;
1066 const float pair_mean_target = plane2[
i * 4 + (orient ? 2 : 1)] * inv_det;
1067 const float mean_guide = plane2[
i * 4 + (orient ? 1 : 2)] * inv_det;
1068 const float var_guide
1069 = fmaxf((orient ? plane2[
i * 4 + 3] : plane3[
i * 4 + 0]) * inv_det - mean_guide * mean_guide,
1071 const float var_t = fmaxf((orient ? plane3[
i * 4 + 0] : plane2[
i * 4 + 3]) * inv_det
1072 - pair_mean_target * pair_mean_target,
1074 const float covariance = plane3[
i * 4 + 1] * inv_det - pair_mean_target * mean_guide;
1076 = covariance / (var_guide * (1.f + 1e-3f) + 1e-12f);
1077 const float r_sq = CLAMP(covariance * covariance / (var_guide * var_t + 1e-18f), 0.f,
1080 valid_variance[
i * 4 + 0] = slope_a;
1082 valid_variance[
i * 4 + 1] = (pair_mean_target + channel_means[target_chan])
1083 - slope_a * (mean_guide + channel_means[guide_chan]);
1084 valid_variance[
i * 4 + 2] = r_sq;
1085 const int mass_ok = (plane3[
i * 4 + 2] > cf_fmin && plane2[
i * 4 + 0] > 0.25f * plane3[
i * 4 + 2]);
1086 hole[
i] = !(mass_ok && valid[
i * 4 + target_chan] >= 0.5f && r_sq > 0.25f && fabsf(slope_a) < 64.f);
1087 if(hole2) hole2[
i] = !(mass_ok && valid[
i * 4 + target_chan] >= 0.5f);
1094 for(
size_t i = 0;
i < region_pixels;
i++)
1096 fill_planes[
i] = valid_variance[
i * 4 + 0];
1097 fill_planes[region_pixels +
i] = valid_variance[
i * 4 + 1];
1098 solver_field[
i] = valid_variance[
i * 4 + 2];
1101 float *planes[2] = { fill_planes, fill_planes + region_pixels };
1103 (
int)(cf_sigma / 4.f), steer, pipe);
1104 _cf_harmonic_fill(solver_field, hole2 ? hole2 : hole, region_w, region_h, (int)(cf_sigma / 4.f), steer,
1108 for(
size_t i = 0;
i < region_pixels;
i++)
1110 valid_variance[
i * 4 + 0] = fill_planes[
i];
1111 valid_variance[
i * 4 + 1] = fill_planes[region_pixels +
i];
1112 valid_variance[
i * 4 + 2] = solver_field[
i];
1130 for(
size_t i = 0;
i < region_pixels;
i++)
1131 if(valid[
i * 4 + target_chan] < 0.5f && valid[
i * 4 + guide_chan] >= 0.5f
1132 && valid[
i * 4 + other_chan] < 0.5f)
1135 estimate[
i * 4 + target_chan]
1136 = valid_variance[
i * 4 + 0] * estimate[
i * 4 + guide_chan] + valid_variance[
i * 4 + 1];
1137 guide_score[
i * 4 + target_chan] = CLAMP(valid_variance[
i * 4 + 2], 0.f, 1.f);
1155 const int guide1 = (cdeep == 0) ? 1 : 0;
1156 const int guide2 = (cdeep == 2) ? 1 : 2;
1159 for(
size_t i = 0;
i < region_pixels;
i++)
1162 = (valid[
i * 4 + cdeep] < 0.5f && (valid[
i * 4 + guide1] < 0.5f || valid[
i * 4 + guide2] < 0.5f)) ? 1.f
1164 blur_in[
i * 4 + 1] = blur_in[
i * 4 + 2] = blur_in[
i * 4 + 3] = 0.f;
1171 for(
size_t i = 0;
i < region_pixels;
i++)
1173 const int anyvalid = (valid[
i * 4 + 0] >= 0.5f) || (valid[
i * 4 + 1] >= 0.5f) || (valid[
i * 4 + 2] >= 0.5f);
1174 if(valid[
i * 4 + cdeep] < 0.5f && anyvalid)
1178 const float joint = reaction_weight[
i] * estimate[
i * 4 + guide1]
1179 + flat_target[
i] * estimate[
i * 4 + guide2] + dome_lum[
i];
1181 const int has_pair = (valid[
i * 4 + guide1] < 0.5f || valid[
i * 4 + guide2] < 0.5f);
1182 const float pair_conf = CLAMP(plane2[
i * 4 + 0], 0.f, 1.f);
1183 const float smooth_t = CLAMP((pair_conf - 0.7f) / 0.25f, 0.f, 1.f);
1184 const float floor_width = has_pair ? smooth_t * smooth_t * (3.f - 2.f * smooth_t) : 0.f;
1185 estimate[
i * 4 + cdeep] = floor_width * estimate[
i * 4 + cdeep] + (1.f - floor_width) * joint;
1186 guide_score[
i * 4 + cdeep] = floor_width * guide_score[
i * 4 + cdeep]
1187 + (1.f - floor_width) * CLAMP(guide_score[
i * 4 + 3], 0.f, 1.f);
1206 memcpy(blur_in, estimate, region_pixels * 4 *
sizeof(
float));
1208 fmaxf(cf_sigma / 4.f, 2.f));
1214 for(
size_t i = 0;
i < region_pixels;
i++)
1216 const float lum_weight = (cf_binv > 0.f) ? sqf(fminf(lum_accum[
i] * cf_binv, 1.f)) : 1.f;
1218 = (valid[
i * 4 + 0] >= 0.5f && valid[
i * 4 + 1] >= 0.5f && valid[
i * 4 + 2] >= 0.5f) ? lum_weight : 0.f;
1221 blur_in[
i * 4 + 1] =
weight * (estimate[
i * 4 + 0] - plane2[
i * 4 + 0]);
1222 blur_in[
i * 4 + 2] =
weight * (estimate[
i * 4 + 1] - plane2[
i * 4 + 1]);
1223 blur_in[
i * 4 + 3] =
weight * (estimate[
i * 4 + 2] - plane2[
i * 4 + 2]);
1230 for(
size_t i = 0;
i < region_pixels;
i++)
1232 const float weight = blur_in[
i * 4 + 0];
1233 const float hf_r = estimate[
i * 4 + 0] - plane2[
i * 4 + 0];
1234 const float hf_g = estimate[
i * 4 + 1] - plane2[
i * 4 + 1];
1235 const float hf_b = estimate[
i * 4 + 2] - plane2[
i * 4 + 2];
1236 blur_in[
i * 4 + 0] =
weight * hf_r * hf_r;
1237 blur_in[
i * 4 + 1] =
weight * hf_g * hf_g;
1238 blur_in[
i * 4 + 2] =
weight * hf_b * hf_b;
1239 blur_in[
i * 4 + 3] =
weight * hf_r * hf_g;
1242 _region_blur(blur_in, plane1, region_w, region_h, cf_sigma);
1245 for(
size_t i = 0;
i < region_pixels;
i++)
1247 const float lum_weight = (cf_binv > 0.f) ? sqf(fminf(lum_accum[
i] * cf_binv, 1.f)) : 1.f;
1249 = (valid[
i * 4 + 0] >= 0.5f && valid[
i * 4 + 1] >= 0.5f && valid[
i * 4 + 2] >= 0.5f) ? lum_weight : 0.f;
1251 =
weight * (estimate[
i * 4 + 0] - plane2[
i * 4 + 0]) * (estimate[
i * 4 + 2] - plane2[
i * 4 + 2]);
1253 =
weight * (estimate[
i * 4 + 1] - plane2[
i * 4 + 1]) * (estimate[
i * 4 + 2] - plane2[
i * 4 + 2]);
1254 blur_in[
i * 4 + 2] = (valid[
i * 4 + 0] >= 0.5f && valid[
i * 4 + 1] >= 0.5f && valid[
i * 4 + 2] >= 0.5f)
1257 blur_in[
i * 4 + 3] = 0.f;
1260 _region_blur(blur_in, plane3, region_w, region_h, cf_sigma);
1265#define HF_M2(nb_index, coef_a, coef_b) \
1266 (((coef_a) == (coef_b)) ? plane1[(nb_index) * 4 + (coef_a)] \
1267 : ((2 + (coef_a) + (coef_b)) < 4 ? plane1[(nb_index) * 4 + 2 + (coef_a) + (coef_b)] \
1268 : plane3[(nb_index) * 4 + (coef_a) + (coef_b) - 2]))
1270 for(
int c = 0; c < 3; c++)
1272 const int guide1 = (c == 0) ? 1 : 0;
1273 const int guide2 = (c == 2) ? 1 : 2;
1276 HL_PFOR(reduction(+ : ntarget))
1277 for(
size_t i = 0;
i < region_pixels;
i++)
1278 if(valid[
i * 4 + c] < 0.5f && valid[
i * 4 + guide1] >= 0.5f && valid[
i * 4 + guide2] >= 0.5f) ntarget++;
1280 if(ntarget == 0)
continue;
1284 for(
size_t i = 0;
i < region_pixels;
i++)
1286 const float norm = fmaxf(prev_scale[
i * 4 + 0], 1e-9f);
1287 const float inv_det = 1.f / norm;
1288 const float mean1 = prev_scale[
i * 4 + 1 + guide1] * inv_det;
1289 const float mean2 = prev_scale[
i * 4 + 1 + guide2] * inv_det;
1290 const float mean_target = prev_scale[
i * 4 + 1 + c] * inv_det;
1293 const float var11 = fmaxf(
HF_M2(
i, guide1, guide1) * inv_det - mean1 * mean1, 0.f);
1294 const float var22 = fmaxf(
HF_M2(
i, guide2, guide2) * inv_det - mean2 * mean2, 0.f);
1295 const float var12 =
HF_M2(
i, guide1, guide2) * inv_det - mean1 * mean2;
1296 const float cov_tg1 =
HF_M2(
i, c, guide1) * inv_det - mean_target * mean1;
1297 const float cov_tg2 =
HF_M2(
i, c, guide2) * inv_det - mean_target * mean2;
1298 const float var_target
1299 = fmaxf(
HF_M2(
i, c, c) * inv_det - mean_target * mean_target, 0.f);
1301 const float lambda = 1e-3f * 0.5f * (var11 + var22) + 1e-12f;
1302 const float determinant = fmaxf((var11 + lambda) * (var22 + lambda) - var12 * var12, 1e-18f);
1303 const float hf_a = ((var22 + lambda) * cov_tg1 - var12 * cov_tg2) / determinant;
1304 const float hf_b_slope = ((var11 + lambda) * cov_tg2 - var12 * cov_tg1) / determinant;
1305 const float hf_r2 = CLAMP((hf_a * cov_tg1 + hf_b_slope * cov_tg2) / (var_target + 1e-12f), 0.f, 1.f);
1308 reaction_weight[
i] = hf_a * hf_r2;
1309 flat_target[
i] = hf_b_slope * hf_r2;
1310 hole[
i] = !(plane3[
i * 4 + 2] > cf_fmin && prev_scale[
i * 4 + 0] > 0.25f * plane3[
i * 4 + 2]
1311 && valid[
i * 4 + c] >= 0.5f && fabsf(reaction_weight[
i]) < 64.f && fabsf(flat_target[
i]) < 64.f);
1316 float *planes[2] = { reaction_weight, flat_target };
1317 _cf_harmonic_fill_n((
float *
const restrict *)planes, 2, hole, region_w, region_h, (
int)(cf_sigma / 4.f),
1323 for(
size_t i = 0;
i < region_pixels;
i++)
1326 const float hf_guided = reaction_weight[
i] * (estimate[
i * 4 + guide1] - plane2[
i * 4 + guide1])
1327 + flat_target[
i] * (estimate[
i * 4 + guide2] - plane2[
i * 4 + guide2]);
1329 const float hf_damped = CLAMP(guide_score[
i * 4 + c], 0.f, 1.f) * (estimate[
i * 4 + c] - plane2[
i * 4 + c]);
1330 blur_in[
i * 4 + 0] = fabsf(hf_guided);
1331 blur_in[
i * 4 + 1] = fabsf(hf_damped);
1332 blur_in[
i * 4 + 2] = 0.f;
1333 blur_in[
i * 4 + 3] = 0.f;
1336 _region_blur(blur_in, valid_variance, region_w, region_h, fmaxf(cf_sigma / 4.f, 2.f));
1340 for(
size_t i = 0;
i < region_pixels;
i++)
1341 if(valid[
i * 4 + c] < 0.5f && valid[
i * 4 + guide1] >= 0.5f && valid[
i * 4 + guide2] >= 0.5f)
1343 const float hf_guided = reaction_weight[
i] * (estimate[
i * 4 + guide1] - plane2[
i * 4 + guide1])
1344 + flat_target[
i] * (estimate[
i * 4 + guide2] - plane2[
i * 4 + guide2]);
1345 const float hf_damped
1346 = CLAMP(guide_score[
i * 4 + c], 0.f, 1.f) * (estimate[
i * 4 + c] - plane2[
i * 4 + c]);
1347 const float energy_g = valid_variance[
i * 4 + 0];
1348 const float energy_d = valid_variance[
i * 4 + 1];
1351 const float energy_weight = energy_d * energy_d / fmaxf(energy_d * energy_d + energy_g * energy_g, 1e-18f);
1353 estimate[
i * 4 + c] = plane2[
i * 4 + c] + energy_weight * hf_guided + (1.f - energy_weight) * hf_damped;
1361 for(
size_t i = 0;
i < region_pixels;
i++)
1363 const int n_valid = (valid[
i * 4 + 0] >= 0.5f) + (valid[
i * 4 + 1] >= 0.5f) + (valid[
i * 4 + 2] >= 0.5f);
1364 if(n_valid != 1)
continue;
1365 for(
int c = 0; c < 3; c++)
1366 if(valid[
i * 4 + c] < 0.5f)
1369 const float hf_weight = CLAMP(guide_score[
i * 4 + c], 0.f, 1.f);
1370 estimate[
i * 4 + c] = plane2[
i * 4 + c] + hf_weight * (estimate[
i * 4 + c] - plane2[
i * 4 + c]);
1394 float region_worth = 1.f;
1396 if(floor_gate > 1e-6f)
1398 float sp0 = 0.f, sp1 = 0.f, sp2 = 0.f, sj0 = 0.f, sj1 = 0.f, sj2 = 0.f;
1399 HL_PFOR(reduction(+ : sp0, sp1, sp2, sj0, sj1, sj2))
1400 for(
size_t i = 0;
i < region_pixels;
i++)
1403 = (valid[
i * 4 + 0] < 0.5f) + (valid[
i * 4 + 1] < 0.5f) + (valid[
i * 4 + 2] < 0.5f);
1404 if(n_clip == 0)
continue;
1406 for(
int c = 0; c < 3; c++)
1407 if(valid[
i * 4 + c] < 0.5f)
1409 const float e = fmaxf(estimate[
i * 4 + c], 1e-6f);
1410 const float c0 = clip0[
i * 4 + c];
1411 const float dd = e - c0, wd = 0.02f * fmaxf(c0, 1e-6f);
1412 const float tgt = c0 + 0.5f * (dd + sqrtf(dd * dd + wd * wd));
1413 lift = fmaxf(lift, fminf(tgt / e, 8.f));
1416 for(
int c = 0; c < 3; c++)
1418 pc[c] = jt[c] = estimate[
i * 4 + c];
1419 if(valid[
i * 4 + c] >= 0.5f)
continue;
1420 const float c0 = clip0[
i * 4 + c], wd = 0.02f * fmaxf(c0, 1e-6f);
1421 const float dd = estimate[
i * 4 + c] - c0;
1422 pc[c] = c0 + 0.5f * (dd + sqrtf(dd * dd + wd * wd));
1423 const float lf = fmaxf(estimate[
i * 4 + c], 1e-6f) * lift, dj = lf - c0;
1424 jt[c] = c0 + 0.5f * (dj + sqrtf(dj * dj + wd * wd));
1426 sp0 += pc[0]; sp1 += pc[1]; sp2 += pc[2];
1427 sj0 += jt[0]; sj1 += jt[1]; sj2 += jt[2];
1429 const float tp = fmaxf(sp0 + sp1 + sp2, 1e-9f), tj = fmaxf(sj0 + sj1 + sj2, 1e-9f);
1430 const float benefit = fabsf(sj0 / tj - sp0 / tp) + fabsf(sj1 / tj - sp1 / tp)
1431 + fabsf(sj2 / tj - sp2 / tp);
1438 if(getenv(
"HL_REGION_W"))
1440 (
unsigned long long)region_pixels, benefit, region_worth);
1444 for(
size_t i = 0;
i < region_pixels;
i++)
1447 if(floor_gate > 1e-6f)
1448 for(
int c = 0; c < 3; c++)
1449 if(valid[
i * 4 + c] < 0.5f)
1451 const float e = fmaxf(estimate[
i * 4 + c], 1e-6f);
1452 const float clip_floor_c = clip0[
i * 4 + c];
1453 const float delta = e - clip_floor_c;
1454 const float weight = 0.02f * fmaxf(clip_floor_c, 1e-6f);
1456 lift = fmaxf(lift, fminf(target / e, 8.f));
1460 float per_chan_v[3], joint_v[3];
1461 for(
int c = 0; c < 3; c++)
1463 per_chan_v[c] = joint_v[c] = estimate[
i * 4 + c];
1464 if(valid[
i * 4 + c] >= 0.5f)
continue;
1465 const float clip_floor_c = clip0[
i * 4 + c];
1466 const float weight = 0.02f * fmaxf(clip_floor_c, 1e-6f);
1467 const float delta = estimate[
i * 4 + c] - clip_floor_c;
1470 const float lifted = fmaxf(estimate[
i * 4 + c], 1e-6f) * lift;
1471 const float delta_joint = lifted - clip_floor_c;
1473 = clip_floor_c + 0.5f * (delta_joint + sqrtf(delta_joint * delta_joint +
weight *
weight));
1475 if(floor_gate <= 1e-6f)
1477 for(
int c = 0; c < 3; c++)
1478 if(valid[
i * 4 + c] < 0.5f) estimate[
i * 4 + c] = per_chan_v[c];
1493 float sum_p = 0.f, sum_j = 0.f;
1494 for(
int c = 0; c < 3; c++)
1496 sum_p += per_chan_v[c];
1497 sum_j += joint_v[c];
1499 sum_p = fmaxf(sum_p, 1e-9f);
1500 sum_j = fmaxf(sum_j, 1e-9f);
1501 float chroma_gain = 0.f;
1502 for(
int c = 0; c < 3; c++) chroma_gain += fabsf(joint_v[c] / sum_j - per_chan_v[c] / sum_p);
1505 const float w = floor_gate * region_worth *
_hl_floor_worth(chroma_gain);
1506 for(
int c = 0; c < 3; c++)
1507 if(valid[
i * 4 + c] < 0.5f)
1508 estimate[
i * 4 + c] = per_chan_v[c] + w * (joint_v[c] - per_chan_v[c]);
1522 for(
size_t i = 0;
i < region_pixels;
i++)
1523 for(
int c = 0; c < 3; c++)
1525 const float dome_t = CLAMP((guide_score[
i * 4 + c] - 0.4f) / 0.45f, 0.f, 1.f);
1526 const float we_r2 = dome_t * dome_t * (3.f - 2.f * dome_t);
1527 const float smooth_t = clip_depth[
i] / (1.5f * cf_sigma);
1528 const float gdep = expf(-smooth_t * smooth_t);
1529 valid_variance[
i * 4 + c] = sqrtf(CLAMP(1.f - (1.f - we_r2) * gdep, 0.f, 1.f));
1559 cl_mem hole,
const int region_w,
const int region_h,
const int base_ds,
1560 const int mask_is_hole, cl_mem steer)
1564 const int downsample = CLAMP(base_ds, 1, 8);
1565 const int base_w = (region_w + downsample - 1) / downsample;
1566 const int base_h = (region_h + downsample - 1) / downsample;
1567 const size_t cell_count = (size_t)base_w * base_h;
1569 const int steered = (steer != NULL);
1578 for(
int plane = 0; plane < n_planes; plane++)
1585 alloc_ok &= (base_vals[plane] && level_vals[plane] && level_solution[plane] && level_scratch[plane]
1586 && prev_level_solution[plane]);
1593 cl_mem base_steer = NULL;
1594 cl_mem level_steer = NULL;
1595 cl_mem steer_blur_lin = NULL;
1596 cl_mem steer_blur_quad = NULL;
1597 cl_mem steer_grad_x = NULL;
1598 cl_mem steer_grad_y = NULL;
1599 cl_mem steer_tensor_xx = NULL;
1600 cl_mem steer_tensor_xy = NULL;
1601 cl_mem steer_tensor_yy = NULL;
1602 cl_mem grad_partial_sums = NULL;
1603 cl_mem grad_mean_norm = NULL;
1604 cl_mem neighbour_weights = NULL;
1605 cl_mem neighbour_weights_sum = NULL;
1621 alloc_ok &= (base_steer && level_steer && steer_blur_lin && steer_blur_quad && steer_grad_x && steer_grad_y
1622 && steer_tensor_xx && steer_tensor_xy && steer_tensor_yy && grad_partial_sums && grad_mean_norm
1623 && neighbour_weights && neighbour_weights_sum)
1627 if(!alloc_ok || !base_anchor_mask || !level_anchor_mask)
goto out;
1633 for(
int plane = 0; plane < n_planes; plane++)
1648 if(cl_err != CL_SUCCESS)
goto out;
1664 if(cl_err != CL_SUCCESS)
goto out;
1670 while((
MAX(base_w, base_h) >> nlev) > 8 && nlev < 12) nlev++;
1674 int prev_level_w = 0;
1675 int prev_level_h = 0;
1676 for(
int level = nlev - 1; level >= 0; level--)
1678 const int step = 1 << level;
1679 const int level_w = (base_w + step - 1) / step;
1680 const int level_h = (base_h + step - 1) / step;
1684 for(
int plane = 0; plane < n_planes; plane++)
1696 const int level_anchor = 0;
1699 if(cl_err != CL_SUCCESS)
goto out;
1702 if(level == nlev - 1)
1705 for(
int plane = 0; plane < n_planes; plane++)
1708 const int n_cells = level_w * level_h;
1709 const int local_size = 256;
1710 size_t size_level[3] = { local_size, 1, 1 };
1711 size_t local[3] = { local_size, 1, 1 };
1719 if(cl_err != CL_SUCCESS)
goto out;
1725 for(
int plane = 0; plane < n_planes; plane++)
1737 if(cl_err != CL_SUCCESS)
goto out;
1749 const int n_cells = level_w * level_h;
1760 if(cl_err != CL_SUCCESS)
goto out;
1762 for(
int pass = 0; pass < 2; pass++)
1765 cl_mem blur_in_lin = pass ? steer_grad_x : level_steer;
1766 cl_mem blur_in_quad = pass ? steer_grad_y : level_steer;
1767 cl_mem outL = pass ? steer_blur_lin : steer_grad_x;
1768 cl_mem outQ = pass ? steer_blur_quad : steer_grad_y;
1769 const int square = (pass == 0);
1778 if(cl_err != CL_SUCCESS)
goto out;
1782 const int local_size = 64, n_groups = 256;
1783 size_t size_1d[3] = { (size_t)n_groups * local_size, 1, 1 };
1784 size_t local_size_1d[3] = { local_size, 1, 1 };
1793 if(cl_err != CL_SUCCESS)
goto out;
1798 const int ngroups = 256;
1799 size_t size_1d[3] = { 1, 1, 1 };
1805 if(cl_err != CL_SUCCESS)
goto out;
1809 size_t size_1d[3] = {
ROUNDUPDWD(n_cells, devid), 1, 1 };
1821 if(cl_err != CL_SUCCESS)
goto out;
1826 if(level_w * level_h <= 4096)
1837 if(cl_err != CL_SUCCESS)
goto out;
1843 if(level_w * level_h <= 4096)
1845 const int iters = 100;
1846 size_t size_box[3] = { 256, 1, 1 };
1847 size_t local_box[3] = { 256, 1, 1 };
1852 cl_mem solution1 = (n_planes > 1) ? level_solution[1] : level_solution[0];
1853 cl_mem solution2 = (n_planes > 2) ? level_solution[2] : level_solution[0];
1854 cl_mem scratch1 = (n_planes > 1) ? level_scratch[1] : level_scratch[0];
1855 cl_mem scratch2 = (n_planes > 2) ? level_scratch[2] : level_scratch[0];
1871 if(cl_err != CL_SUCCESS)
goto out;
1874 for(
int plane = 0; plane < n_planes; plane++)
1885 if(cl_err != CL_SUCCESS)
goto out;
1889 for(
int plane = 0; plane < n_planes; plane++)
1891 cl_mem swap_buf = prev_level_solution[plane];
1892 prev_level_solution[plane] = level_solution[plane];
1893 level_solution[plane] = swap_buf;
1895 prev_level_w = level_w;
1896 prev_level_h = level_h;
1901 const int n_iter = 100;
1903 for(
int plane = 0; plane < n_planes; plane++)
1905 solution_planes[plane] = level_solution[plane];
1906 scratch_planes[plane] = level_scratch[plane];
1908 for(
int iter = 0; iter < n_iter; iter++)
1916 cl_mem solution1 = (n_planes > 1) ? solution_planes[1] : solution_planes[0];
1917 cl_mem solution2 = (n_planes > 2) ? solution_planes[2] : solution_planes[0];
1918 cl_mem scratch1 = (n_planes > 1) ? scratch_planes[1] : scratch_planes[0];
1919 cl_mem scratch2 = (n_planes > 2) ? scratch_planes[2] : scratch_planes[0];
1935 if(cl_err != CL_SUCCESS)
goto out;
1938 for(
int plane = 0; plane < n_planes; plane++)
1948 if(cl_err != CL_SUCCESS)
goto out;
1950 for(
int plane = 0; plane < n_planes; plane++)
1952 cl_mem swap_buf = solution_planes[plane];
1953 solution_planes[plane] = scratch_planes[plane];
1954 scratch_planes[plane] = swap_buf;
1959 for(
int plane = 0; plane < n_planes; plane++)
1961 cl_mem swap_buf = prev_level_solution[plane];
1962 prev_level_solution[plane] = solution_planes[plane];
1963 solution_planes[plane] = swap_buf;
1964 level_solution[plane]
1965 = (prev_level_solution[plane] == level_solution[plane]) ? solution_planes[plane] : level_solution[plane];
1966 level_scratch[plane]
1967 = (prev_level_solution[plane] == level_scratch[plane]) ? solution_planes[plane] : level_scratch[plane];
1969 prev_level_w = level_w;
1970 prev_level_h = level_h;
1975 for(
int plane = 0; plane < n_planes; plane++)
1989 if(cl_err != CL_SUCCESS)
goto out;