/* * Copyright 2020 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Authors: AMD *
*/
/* driver uses 32 regions or less, but DCN HW has 34, extra 2 are set to 0 */ #define MAX_REGIONS_NUMBER 34 #define MAX_LOW_POINT 25 #define NUMBER_REGIONS 32 #define NUMBER_SW_SEGMENTS 16
if (output_tf->tf == TRANSFER_FUNCTION_PQ || output_tf->tf == TRANSFER_FUNCTION_GAMMA22 ||
output_tf->tf == TRANSFER_FUNCTION_HLG) { /* 32 segments * segments are from 2^-25 to 2^7
*/ for (i = 0; i < NUMBER_REGIONS ; i++)
seg_distr[i] = 3;
region_start = -MAX_LOW_POINT;
region_end = NUMBER_REGIONS - MAX_LOW_POINT;
} else { /* 13 segments * segment is from 2^-12 to 2^0 * There are less than 256 points, for optimization
*/ const uint8_t SEG_COUNT = 12;
for (i = 0; i < SEG_COUNT; i++)
seg_distr[i] = 4;
seg_distr[SEG_COUNT] = 1;
region_start = -SEG_COUNT;
region_end = 1;
}
for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++)
seg_distr[i] = -1;
for (k = 0; k < MAX_REGIONS_NUMBER; k++) { if (seg_distr[k] != -1)
hw_points += (1 << seg_distr[k]);
}
j = 0; for (k = 0; k < (region_end - region_start); k++) {
increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]);
start_index = (region_start + k + MAX_LOW_POINT) *
NUMBER_SW_SEGMENTS; for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS;
i += increment) { if (j == hw_points) break; if (i >= TRANSFER_FUNC_POINTS) returnfalse;
rgb_resulted[j].red = output_tf->tf_pts.red[i];
rgb_resulted[j].green = output_tf->tf_pts.green[i];
rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
j++;
}
}
/* last point */
start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS;
rgb_resulted[hw_points].red = output_tf->tf_pts.red[start_index];
rgb_resulted[hw_points].green = output_tf->tf_pts.green[start_index];
rgb_resulted[hw_points].blue = output_tf->tf_pts.blue[start_index];
// All 3 color channels have same x
corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2),
dc_fixpt_from_int(region_start));
corner_points[0].green.x = corner_points[0].red.x;
corner_points[0].blue.x = corner_points[0].red.x;
/* see comment above, m_arrPoints[1].y should be the Y value for the * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1)
*/
corner_points[1].red.y = rgb_resulted[hw_points].red;
corner_points[1].green.y = rgb_resulted[hw_points].green;
corner_points[1].blue.y = rgb_resulted[hw_points].blue;
corner_points[1].red.slope = dc_fixpt_zero;
corner_points[1].green.slope = dc_fixpt_zero;
corner_points[1].blue.slope = dc_fixpt_zero;
// DCN3+ have 257 pts in lieu of no separate slope registers // Prior HW had 256 base+slope pairs
lut_params->hw_points_num = hw_points + 1;
k = 0; for (i = 1; i < MAX_REGIONS_NUMBER; i++) { if (seg_distr[k] != -1) {
lut_params->arr_curve_points[k].segments_num =
seg_distr[k];
lut_params->arr_curve_points[i].offset =
lut_params->arr_curve_points[k].offset + (1 << seg_distr[k]);
}
k++;
}
if (seg_distr[k] != -1)
lut_params->arr_curve_points[k].segments_num = seg_distr[k];
if (fixpoint == true) {
i = 1; while (i != hw_points + 2) { if (i >= hw_points) { if (dc_fixpt_lt(rgb_plus_1->red, rgb->red))
rgb_plus_1->red = dc_fixpt_add(rgb->red,
rgb_minus_1->delta_red); if (dc_fixpt_lt(rgb_plus_1->green, rgb->green))
rgb_plus_1->green = dc_fixpt_add(rgb->green,
rgb_minus_1->delta_green); if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue))
rgb_plus_1->blue = dc_fixpt_add(rgb->blue,
rgb_minus_1->delta_blue);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.