/* * Copyright 2016 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 *
*/ #include"dc.h" #include"reg_helper.h" #include"dcn10/dcn10_dpp.h"
while (i != hw_points_num) { if (!convert_to_custom_float_format(rgb->red, &fmt,
&rgb->red_reg)) {
BREAK_TO_DEBUGGER(); returnfalse;
}
if (!convert_to_custom_float_format(rgb->green, &fmt,
&rgb->green_reg)) {
BREAK_TO_DEBUGGER(); returnfalse;
}
if (!convert_to_custom_float_format(rgb->blue, &fmt,
&rgb->blue_reg)) {
BREAK_TO_DEBUGGER(); returnfalse;
}
if (!convert_to_custom_float_format(rgb->delta_red, &fmt,
&rgb->delta_red_reg)) {
BREAK_TO_DEBUGGER(); returnfalse;
}
if (!convert_to_custom_float_format(rgb->delta_green, &fmt,
&rgb->delta_green_reg)) {
BREAK_TO_DEBUGGER(); returnfalse;
}
if (!convert_to_custom_float_format(rgb->delta_blue, &fmt,
&rgb->delta_blue_reg)) {
BREAK_TO_DEBUGGER(); returnfalse;
}
++rgb;
++i;
}
returntrue;
}
/* 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) { /* 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 - 1) break; if (i >= TRANSFER_FUNC_POINTS) {
DC_LOG_ERROR("Index out of bounds: i=%d, TRANSFER_FUNC_POINTS=%d\n",
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++;
}
}
// 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 - 1].red;
corner_points[1].green.y = rgb_resulted[hw_points - 1].green;
corner_points[1].blue.y = rgb_resulted[hw_points - 1].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;
if (output_tf->tf == TRANSFER_FUNCTION_PQ) { /* for PQ, we want to have a straight line from last HW X point, * and the slope to be such that we hit 1.0 at 10000 nits.
*/ conststruct fixed31_32 end_value =
dc_fixpt_from_int(125);
for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++)
seg_distr[i] = -1; /* 12 segments * segments are from 2^-12 to 0
*/ for (i = 0; i < NUM_DEGAMMA_REGIONS ; i++)
seg_distr[i] = 4;
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 - 1) 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++;
}
}
/* 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 - 1].red;
corner_points[1].green.y = rgb_resulted[hw_points - 1].green;
corner_points[1].blue.y = rgb_resulted[hw_points - 1].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;
if (output_tf->tf == TRANSFER_FUNCTION_PQ) { /* for PQ, we want to have a straight line from last HW X point, * and the slope to be such that we hit 1.0 at 10000 nits.
*/ conststruct fixed31_32 end_value =
dc_fixpt_from_int(125);
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.