AMDgpu 显示管理器¶
AMDgpu 显示管理器 amdgpu_dm (或更简单的 dm)位于 DRM 和 DC 之间。它充当联络人,将 DRM 请求转换为 DC 请求,并将 DC 响应转换为 DRM 响应。
根控制结构是 struct amdgpu_display_manager
。
-
struct dm_compressor_info¶
帧缓冲区压缩使用的缓冲区信息
定义:
struct dm_compressor_info {
void *cpu_addr;
struct amdgpu_bo *bo_ptr;
uint64_t gpu_addr;
};
成员
cpu_addr
MMIO CPU 地址
bo_ptr
指向缓冲区对象的指针
gpu_addr
MMIO GPU 地址
-
struct dmub_hpd_work¶
处理低优先级邮箱 IRQ 中的耗时工作
定义:
struct dmub_hpd_work {
struct work_struct handle_hpd_work;
struct dmub_notification *dmub_notify;
struct amdgpu_device *adev;
};
成员
handle_hpd_work
要在单独的线程中执行以处理 hpd_low_irq 的工作
dmub_notify
回调函数的通知
adev
amdgpu_device 指针
-
struct vblank_control_work¶
垂直消隐控制的工作数据
定义:
struct vblank_control_work {
struct work_struct work;
struct amdgpu_display_manager *dm;
struct amdgpu_crtc *acrtc;
struct dc_stream_state *stream;
bool enable;
};
成员
work
工作事件的内核工作数据
dm
amdgpu 显示管理器设备
acrtc
发生事件的 amdgpu CRTC 实例
stream
发生事件的 DC 流
enable
如果启用垂直消隐则为 true
-
struct idle_workqueue¶
空闲时定期操作的工作数据
定义:
struct idle_workqueue {
struct work_struct work;
struct amdgpu_display_manager *dm;
bool enable;
bool running;
};
成员
work
工作事件的内核工作数据
dm
amdgpu 显示管理器设备
enable
如果启用空闲工作线程则为 true
running
如果空闲工作线程正在运行则为 true
-
struct amdgpu_dm_backlight_caps¶
有关背光的信息
定义:
struct amdgpu_dm_backlight_caps {
union dpcd_sink_ext_caps *ext_caps;
u32 aux_min_input_signal;
u32 aux_max_input_signal;
int min_input_signal;
int max_input_signal;
bool caps_valid;
bool aux_support;
u8 ac_level;
u8 dc_level;
};
成员
ext_caps
使用有关 HDR 显示支持的所有信息保存数据结构。
aux_min_input_signal
显示器支持的最小亮度值
aux_max_input_signal
显示器支持的最大亮度值,单位为尼特。
min_input_signal
范围 0-255 中的最小可能输入。
max_input_signal
范围 0-255 中的最大可能输入。
caps_valid
如果这些值来自 ACPI 接口则为 true。
aux_support
描述显示器是否支持 AUX 背光。
ac_level
如果使用 AC 启动的默认亮度
dc_level
如果使用 DC 启动的默认亮度
描述
描述 ACPI 或 eDP AUX 的背光支持。
-
struct dal_allocation¶
跟踪用于 SMU 通信的已映射 FB 内存
定义:
struct dal_allocation {
struct list_head list;
struct amdgpu_bo *bo;
void *cpu_ptr;
u64 gpu_addr;
};
成员
list
dal 分配列表
bo
GPU 缓冲区对象
cpu_ptr
GPU 缓冲区对象的 CPU 虚拟地址
gpu_addr
GPU 缓冲区对象的 GPU 虚拟地址
-
struct hpd_rx_irq_offload_work_queue¶
处理 hpd_rx_irq 卸载工作的工作队列
定义:
struct hpd_rx_irq_offload_work_queue {
struct workqueue_struct *wq;
spinlock_t offload_lock;
bool is_handling_link_loss;
bool is_handling_mst_msg_rdy_event;
struct amdgpu_dm_connector *aconnector;
};
成员
wq
用于排队卸载工作的工作队列结构。
offload_lock
保护卸载工作队列的字段。
is_handling_link_loss
用于防止在我们处理链路丢失时插入链路丢失事件
is_handling_mst_msg_rdy_event
用于防止在我们已在处理 mst 消息就绪事件时插入 mst 消息就绪事件
aconnector
此工作队列所附加到的 aconnector
-
struct hpd_rx_irq_offload_work¶
hpd_rx_irq 卸载工作结构
定义:
struct hpd_rx_irq_offload_work {
struct work_struct work;
union hpd_irq_data data;
struct hpd_rx_irq_offload_work_queue *offload_wq;
};
成员
work
卸载工作
data
在处理卸载工作时使用的参考 irq 数据
offload_wq
此工作排队到的卸载工作队列
-
struct amdgpu_display_manager¶
中央 amdgpu 显示管理器设备
定义:
struct amdgpu_display_manager {
struct dc *dc;
struct dmub_srv *dmub_srv;
struct dmub_notification *dmub_notify;
dmub_notify_interrupt_callback_t dmub_callback[AMDGPU_DMUB_NOTIFICATION_MAX];
bool dmub_thread_offload[AMDGPU_DMUB_NOTIFICATION_MAX];
struct dmub_srv_fb_info *dmub_fb_info;
const struct firmware *dmub_fw;
struct amdgpu_bo *dmub_bo;
u64 dmub_bo_gpu_addr;
void *dmub_bo_cpu_addr;
uint32_t dmcub_fw_version;
struct cgs_device *cgs_device;
struct amdgpu_device *adev;
struct drm_device *ddev;
u16 display_indexes_num;
struct drm_private_obj atomic_obj;
struct mutex dc_lock;
struct mutex audio_lock;
struct drm_audio_component *audio_component;
bool audio_registered;
struct list_head irq_handler_list_low_tab[DAL_IRQ_SOURCES_NUMBER];
struct list_head irq_handler_list_high_tab[DAL_IRQ_SOURCES_NUMBER];
struct common_irq_params pflip_params[DC_IRQ_SOURCE_PFLIP_LAST - DC_IRQ_SOURCE_PFLIP_FIRST + 1];
struct common_irq_params vblank_params[DC_IRQ_SOURCE_VBLANK6 - DC_IRQ_SOURCE_VBLANK1 + 1];
struct common_irq_params vline0_params[DC_IRQ_SOURCE_DC6_VLINE0 - DC_IRQ_SOURCE_DC1_VLINE0 + 1];
struct common_irq_params vupdate_params[DC_IRQ_SOURCE_VUPDATE6 - DC_IRQ_SOURCE_VUPDATE1 + 1];
struct common_irq_params dmub_trace_params[1];
struct common_irq_params dmub_outbox_params[1];
spinlock_t irq_handler_list_table_lock;
struct backlight_device *backlight_dev[AMDGPU_DM_MAX_NUM_EDP];
const struct dc_link *backlight_link[AMDGPU_DM_MAX_NUM_EDP];
uint8_t num_of_edps;
struct amdgpu_dm_backlight_caps backlight_caps[AMDGPU_DM_MAX_NUM_EDP];
struct mod_freesync *freesync_module;
struct hdcp_workqueue *hdcp_workqueue;
struct workqueue_struct *vblank_control_workqueue;
struct idle_workqueue *idle_workqueue;
struct drm_atomic_state *cached_state;
struct dc_state *cached_dc_state;
struct dm_compressor_info compressor;
const struct firmware *fw_dmcu;
uint32_t dmcu_fw_version;
const struct gpu_info_soc_bounding_box_v1_0 *soc_bounding_box;
uint32_t active_vblank_irq_count;
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY);
struct secure_display_context *secure_display_ctxs;
#endif;
struct hpd_rx_irq_offload_work_queue *hpd_rx_offload_wq;
struct amdgpu_encoder mst_encoders[AMDGPU_DM_MAX_CRTC];
bool force_timing_sync;
bool disable_hpd_irq;
bool dmcub_trace_event_en;
struct list_head da_list;
struct completion dmub_aux_transfer_done;
struct workqueue_struct *delayed_hpd_wq;
u32 brightness[AMDGPU_DM_MAX_NUM_EDP];
u32 actual_brightness[AMDGPU_DM_MAX_NUM_EDP];
bool aux_hpd_discon_quirk;
struct mutex dpia_aux_lock;
struct dml2_soc_bb *bb_from_dmub;
};
成员
dc
显示核心控制结构
dmub_srv
DMUB 服务,用于控制支持它的硬件上的 DMUB。在不支持它的硬件上,指向 dmub_srv 的指针将为 NULL。
dmub_notify
来自 DMUB 的通知。
dmub_callback
用于处理来自 DMUB 的通知的回调函数。
dmub_thread_offload
指示回调是否卸载的标志。
dmub_fb_info
DMUB 的帧缓冲区区域。
dmub_fw
具有 DMUB 支持的硬件上需要的 DMUB 固件。
dmub_bo
DMUB 的缓冲区对象。
dmub_bo_gpu_addr
DMUB 缓冲区对象的 GPU 虚拟地址。
dmub_bo_cpu_addr
DMUB 缓冲区对象的 CPU 地址。
dmcub_fw_version
DMCUB 固件版本。
cgs_device
通用图形服务设备。它提供了一个用于访问寄存器的接口。
adev
AMDGPU 基本驱动程序结构
ddev
DRM 基本驱动程序结构
display_indexes_num
支持的最大显示流数
atomic_obj
与
dm_atomic_state
结合使用,它有助于管理不能干净地映射到现有 drm 资源的全局原子状态,例如dc_context
。dc_lock
保护对可以发出寄存器写入序列的 DC 函数的访问。
audio_lock
保护对音频实例更改的访问。
audio_component
用于通知声音驱动程序 ELD 更改。
audio_registered
如果音频组件已成功注册,则为 True,否则为 false。
irq_handler_list_low_tab
低优先级 IRQ 处理程序表。
它是一个 n*m 表,由 n 个 IRQ 源和每个 IRQ 源 m 个处理程序组成。低优先级 IRQ 处理程序会延迟到工作队列进行处理。因此,它们可以休眠。
请注意,处理程序的调用顺序与它们注册的顺序相同 (FIFO)。
irq_handler_list_high_tab
高优先级 IRQ 处理程序表。
它是一个 n*m 表,与
irq_handler_list_low_tab
相同。但是,此表中的处理程序不会延迟,并会立即调用。pflip_params
页面翻转 IRQ 参数,在触发时传递给已注册的处理程序。
vblank_params
垂直消隐 IRQ 参数,在触发时传递给已注册的处理程序。
vline0_params
OTG 垂直中断 0 IRQ 参数,在触发时传递给已注册的处理程序。
vupdate_params
垂直更新 IRQ 参数,在触发时传递给已注册的处理程序。
dmub_trace_params
DMUB 跟踪事件 IRQ 参数,在触发时传递给已注册的处理程序。
dmub_outbox_params
DMUB 邮箱参数
irq_handler_list_table_lock
同步对 IRQ 表的访问
backlight_dev
背光控制设备
backlight_link
用于控制背光的链路
num_of_edps
背光 eDP 的数量
backlight_caps
背光设备的功能
freesync_module
处理 freesync 计算的模块
hdcp_workqueue
AMDGPU 内容保护队列
vblank_control_workqueue
用于垂直消隐控制事件的延迟工作。
idle_workqueue
用于空闲事件的定期工作。
cached_state
缓存用于挂起/恢复的设备原子状态
cached_dc_state
内容流的缓存状态
compressor
帧缓冲区压缩缓冲区。请参阅
struct dm_compressor_info
fw_dmcu
对 DMCU 固件的引用
dmcu_fw_version
DMCU 固件的版本
soc_bounding_box
gpu_info FW 提供的 soc 边界框结构,如果 FW 中不可用,则为 0
active_vblank_irq_count
当前活动垂直消隐 irq 的数量
secure_display_ctxs
存储所有 crtc 的 ROI 信息和用于命令 dmub 和 psp 的 work_struct。
hpd_rx_offload_wq
用于卸载 hpd_rx_irq 工作的工作队列
mst_encoders
用于 DP MST 的伪编码器。
force_timing_sync
通过 debugfs 设置。设置后,指示所有连接的显示器将被强制同步。
disable_hpd_irq
如果为 true,则禁用驱动程序中的所有 HPD 和 HPD RX 中断处理
dmcub_trace_event_en
启用 dmcub 跟踪事件
da_list
DAL fb 内存分配列表,用于与 SMU 通信。
dmub_aux_transfer_done
用于指示 DMUB 传输何时完成的 struct 完成
delayed_hpd_wq
用于延迟 DMUB HPD 工作的工作队列
brightness
缓存的背光值。
actual_brightness
上次成功应用的背光值。
aux_hpd_discon_quirk
当 aux 正在进行时发生 hpd 断开连接的怪异现象。发生在某些 Intel 平台上
dpia_aux_lock
保护对 DPIA AUX 的访问
bb_from_dmub
在 DCN4+ 的早期初始化期间从 dmub 读取的边界框数据
-
struct amdgpu_hdmi_vsdb_info¶
跟踪 VSDB 信息
定义:
struct amdgpu_hdmi_vsdb_info {
unsigned int amd_vsdb_version;
bool freesync_supported;
unsigned int min_refresh_rate_hz;
unsigned int max_refresh_rate_hz;
bool replay_mode;
};
成员
amd_vsdb_version
厂商特定数据块版本,应用于确定要发送哪个厂商特定信息帧 (VSIF)。
freesync_supported
支持 FreeSync。
min_refresh_rate_hz
FreeSync 的最低刷新率,单位为 Hz。
max_refresh_rate_hz
FreeSync 的最高刷新率,单位为 Hz。
replay_mode
支持重放
描述
AMDGPU 通过使用 VSDB 部分来支持 HDMI 上的 FreeSync,此结构体用于跟踪有关 FreeSync 的显示特定信息。
生命周期¶
DM(以及随后的 DC)在 amdgpu 基本驱动程序中注册为 IP 块。当启用 CONFIG_DRM_AMD_DC 时,DM 设备 IP 块将添加到基本驱动程序的设备列表中,以便进行相应的初始化和拆卸。
执行此操作的函数在 struct amd_ip_funcs
中作为钩子提供。
-
int dm_hw_init(struct amdgpu_ip_block *ip_block)¶
初始化 DC 设备
参数
struct amdgpu_ip_block *ip_block
指向此硬件实例的 amdgpu_ip_block 的指针。
描述
初始化 struct amdgpu_display_manager
设备。这包括调用每个 DM 组件的初始化器,然后使用它们填充结构体。
尽管该函数暗示硬件初始化,但此处初始化的是硬件和软件。将它们拆分到它们相关的初始化钩子是未来的 TODO 项。
此处初始化的一些值得注意的事项
显示核心,包括软件和硬件
我们需要的 DC 模块(FreeSync 和颜色管理)
DRM 软件状态
中断源和处理程序
垂直消隐支持
调试 FS 条目(如果启用)
-
int dm_hw_fini(struct amdgpu_ip_block *ip_block)¶
拆卸 DC 设备
参数
struct amdgpu_ip_block *ip_block
指向此硬件实例的 amdgpu_ip_block 的指针。
描述
拆卸 struct amdgpu_display_manager
中需要清理的组件。这包括清理 DRM 设备、DC 和任何已加载的模块。此外,刷新 IRQ 工作队列并禁用它们。
中断¶
DM 在基本驱动程序已提供的基础上提供了另一层 IRQ 管理。这是可以清理的事情,并且是未来的 TODO 项。
基本驱动程序提供带有 DRM 的 IRQ 源注册、注册到基本驱动程序 IRQ 表中的处理程序以及一个处理程序回调 amdgpu_irq_handler()
,DRM 在发生中断时调用该回调。此通用处理程序查找 IRQ 表,并调用相应的 amdgpu_irq_src_funcs.process
钩子。
DM 在此基础上提供的两个 IRQ 表专门用于上半部分和下半部分 IRQ 处理,其中下半部分实现工作队列
它们会覆盖基本驱动程序的 IRQ 表,并且可以在 DM 为 amdgpu_irq_src_funcs.process
提供的钩子中看到效果。它们全部设置为 DM 通用处理程序 amdgpu_dm_irq_handler()
,该处理程序会查找 DM 的 IRQ 表。但是,为了使基本驱动程序识别此钩子,DM 仍需要向基本驱动程序注册 IRQ。请参见 dce110_register_irq_handlers() 和 dcn10_register_irq_handlers()。
为了将 DC 的硬件中断切换公开给基本驱动程序,DM 实现了 amdgpu_irq_src_funcs.set
钩子。基本驱动程序通过 amdgpu_irq_update()
调用它来启用或禁用中断。
-
struct amdgpu_dm_irq_handler_data¶
DM 中断处理程序的数据。
定义:
struct amdgpu_dm_irq_handler_data {
struct list_head list;
interrupt_handler handler;
void *handler_arg;
struct amdgpu_display_manager *dm;
enum dc_irq_source irq_source;
struct work_struct work;
};
成员
list
引用下一个/上一个处理程序的链表条目
handler
处理程序函数
handler_arg
触发时传递给处理程序的参数
dm
此处理程序所属的 DM
irq_source
为此处理程序注册的 DC 中断源
work
work struct
-
void dm_irq_work_func(struct work_struct *work)¶
在中断处理程序之外处理 IRQ。
参数
struct work_struct *work
work struct
-
void unregister_all_irq_handlers(struct amdgpu_device *adev)¶
从 DM IRQ 表中清除处理程序
参数
struct amdgpu_device *adev
包含 DM 设备的基本驱动程序设备
描述
遍历低上下文和高上下文 IRQ 表,并取消分配处理程序。
-
void *amdgpu_dm_irq_register_interrupt(struct amdgpu_device *adev, struct dc_interrupt_params *int_params, void (*ih)(void*), void *handler_args)¶
在 DM 中注册处理程序。
参数
struct amdgpu_device *adev
包含 DM 设备的基本驱动程序设备。
struct dc_interrupt_params *int_params
包含源和处理程序上下文的中断参数
void (*ih)(void *)
指向要注册的中断处理程序的函数指针
void *handler_args
发生中断时传递给处理程序的参数
描述
在给定上下文中为给定 IRQ 源注册中断处理程序。上下文可以是高上下文或低上下文。高上下文处理程序直接在 ISR 上下文中执行,而低上下文处理程序在工作队列中执行,从而允许休眠操作。
注册的处理程序按 FIFO 方式调用,即最近注册的处理程序将首先调用。
返回
- 包含 IRQ 的处理程序数据
struct amdgpu_dm_irq_handler_data
源、处理程序函数和参数
-
void amdgpu_dm_irq_unregister_interrupt(struct amdgpu_device *adev, enum dc_irq_source irq_source, void *ih)¶
从 DM IRQ 表中删除处理程序
参数
struct amdgpu_device *adev
包含 DM 设备的基本驱动程序设备
enum dc_irq_source irq_source
从中删除给定处理程序的 IRQ 源
void *ih
指向要取消注册的中断处理程序的函数指针
描述
遍历低上下文和高上下文 IRQ 表,并查找给定 IRQ 源的给定处理程序。如果找到,则将其删除。否则,不执行任何操作。
-
int amdgpu_dm_irq_init(struct amdgpu_device *adev)¶
初始化 DM IRQ 管理
参数
struct amdgpu_device *adev
包含 DM 设备的基本驱动程序设备
描述
初始化 DM 的高上下文和低上下文 IRQ 表。
N x M 表包含 N 个 IRQ 源,其中 M 个 struct amdgpu_dm_irq_handler_data
在一个链表中连接在一起。此处初始化 list_heads。当触发中断 n 时,所有 m 个处理程序都将按注册顺序以 FIFO 顺序调用。
低上下文表需要特殊的初始化步骤,因为处理程序将推迟到工作队列。请参见 struct irq_list_head
。
-
void amdgpu_dm_irq_fini(struct amdgpu_device *adev)¶
拆除 DM IRQ 管理。
参数
struct amdgpu_device *adev
包含 DM 设备的基本驱动程序设备
描述
刷新低上下文 IRQ 表中的所有工作。
-
int amdgpu_dm_irq_handler(struct amdgpu_device *adev, struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry)¶
通用 DM IRQ 处理程序
参数
struct amdgpu_device *adev
包含 DM 设备的 amdgpu 基础驱动程序设备
struct amdgpu_irq_src *source
未使用
struct amdgpu_iv_entry *entry
有关触发中断的数据
描述
立即调用所有注册的高 IRQ 工作,并为低 IRQ 安排工作。 DM IRQ 表用于查找相应的处理程序。
-
void amdgpu_dm_hpd_init(struct amdgpu_device *adev)¶
hpd 设置回调。
参数
struct amdgpu_device *adev
amdgpu_device 指针
描述
设置卡使用的 hpd 引脚(evergreen+)。启用引脚,设置极性,并启用 hpd 中断。
-
void amdgpu_dm_hpd_fini(struct amdgpu_device *adev)¶
hpd 拆除回调。
参数
struct amdgpu_device *adev
amdgpu_device 指针
描述
拆除卡使用的 hpd 引脚(evergreen+)。禁用 hpd 中断。
-
void dm_pflip_high_irq(void *interrupt_params)¶
处理页面翻转中断
参数
void *interrupt_params
已忽略
描述
通过通知所有相关方页面翻转已完成来处理页面翻转中断。
-
void dm_crtc_high_irq(void *interrupt_params)¶
处理 CRTC 中断
参数
void *interrupt_params
用于确定 CRTC 实例
描述
通过通知 DRM 的 VBLANK 事件处理程序来处理 CRTC/VSYNC 中断。
原子实现¶
WIP
-
void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)¶
AMDgpu DM 的提交尾部实现。
参数
struct drm_atomic_state *state
要提交的原子状态
描述
这将告诉 DC 提交从 atomic_check 构建的 DC 状态,从而对硬件进行编程。此处的任何失败都意味着硬件故障,因为原子检查应该已经过滤掉了任何不合规的内容。
-
int amdgpu_dm_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)¶
AMDgpu DM 的原子检查实现。
参数
struct drm_device *dev
DRM 设备
struct drm_atomic_state *state
要提交的原子状态
描述
验证给定的原子状态是否可以通过 DC 编程到硬件中。这涉及到构造一个 struct dc_state
,反映我们希望提交的新硬件状态,然后查询 DC 以查看它是否可编程。重要的是不要修改现有的 DC 状态。否则,atomic_check 可能会意外提交硬件更改。
在验证 DC 状态时,重要的是获取正确的锁。对于在翻转另一个 CRTC 时删除/添加/更新一个 CRTC 上的流的完全更新情况,获取全局锁将保证任何此类完全更新提交都将等待使用 DRM 同步事件的任何未完成翻转完成。
请注意,DM 为状态中的所有 CRTC 添加了受影响的连接器,即使这似乎不是必需的。这是因为 DC 流创建需要 DC sink,而 DC sink 与 DRM 连接器状态相关联。清理此问题应该是可行的,但并非微不足道 - 这是一个可能的 TODO 项。
返回
- 如果验证失败,则返回错误代码。
颜色管理属性¶
到硬件的 DC 接口为我们提供了每个管道(表面)的以下颜色管理块
输入伽马 LUT(非归一化)
输入 CSC(归一化)
表面去伽马 LUT(归一化)
表面 CSC(归一化)
表面再伽马 LUT(归一化)
输出 CSC(归一化)
但是,这些与 DRM 颜色属性没有直接映射。当前的 DRM 接口公开了 CRTC 去伽马、CRTC CTM 和 CRTC 再伽马,而我们的硬件本质上提供
平面 CTM -> 平面去伽马 -> 平面 CTM -> 平面再伽马 -> 平面 CTM
输入伽马 LUT 块在这里不是真正适用的,因为它作用于实际的输入数据本身,而不是 HW fp 表示。输入和输出 CSC 块在技术上可作为 DC 接口的一部分使用,但通常由 DC 内部用于颜色空间之间的转换。将来可以将这些与用户调整混合在一起,但现在这些应保持不变。
管道混合也发生在这些块之后,因此我们实际上不支持任何具有多个平面正确混合的 CRTC 属性 - 但我们仍然可以通过在 DM 中巧妙管理 DC 接口,在大多数单平面情况下正确支持 DM 中的 CRTC 颜色管理属性。
根据 DRM 文档,当各自的属性设置为 NULL 时,块应处于硬件旁路中。线性 DGM/RGM LUT 也应被视为将各自的块置于旁路模式。
这意味着以下配置被假定为默认配置
平面 DGM 旁路 -> 平面 CTM 旁路 -> 平面 RGM 旁路 -> ... CRTC DGM 旁路 -> CRTC CTM 旁路 -> CRTC RGM 旁路
-
void amdgpu_dm_init_color_mod(void)¶
初始化颜色模块。
参数
void
无参数
描述
我们不使用完整的颜色模块,仅使用某些组件。仅对我们需要使用的组件调用设置函数。
-
const struct drm_color_lut *__extract_blob_lut(const struct drm_property_blob *blob, uint32_t *size)¶
从 blob 中提取 DRM lut 和 lut 大小。
参数
const struct drm_property_blob *blob
DRM 颜色管理属性 blob
uint32_t *size
lut 大小
返回
DRM LUT 或 NULL
-
bool __is_lut_linear(const struct drm_color_lut *lut, uint32_t size)¶
检查给定的 lut 是否是值的线性映射
参数
const struct drm_color_lut *lut
要检查值的给定 lut
uint32_t size
lut 大小
描述
如果 lut 表示:f(a) = (0xFF00/MAX_COLOR_LUT_ENTRIES-1)a;对于 [0, MAX_COLOR_LUT_ENTRIES) 中的整数 a,则认为它是线性的
返回
如果给定 lut 是值的线性映射,即它的作用类似于旁路 LUT,则返回 true。否则,返回 false。
-
void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut, struct dc_gamma *gamma, bool is_legacy)¶
将 drm_color_lut 转换为 dc_gamma。
参数
const struct drm_color_lut *lut
用于颜色转换的 DRM 查找表
struct dc_gamma *gamma
要设置条目的 DC 伽马
bool is_legacy
传统伽马或原子伽马
描述
转换取决于 lut 的大小 - 无论它是否是传统的。
-
void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm, struct fixed31_32 *matrix)¶
将 DRM CTM 转换为 DC CSC 浮点矩阵
参数
const struct drm_color_ctm *ctm
DRM 颜色转换矩阵
struct fixed31_32 *matrix
DC CSC 浮点矩阵
描述
该矩阵需要是一个 3x4(12 个条目)的矩阵。
-
void __drm_ctm_3x4_to_dc_matrix(const struct drm_color_ctm_3x4 *ctm, struct fixed31_32 *matrix)¶
将 DRM CTM 3x4 转换为 DC CSC 浮点矩阵
参数
const struct drm_color_ctm_3x4 *ctm
具有 3x4 维度的 DRM 颜色转换矩阵
struct fixed31_32 *matrix
DC CSC 浮点矩阵
描述
该矩阵需要是一个 3x4(12 个条目)的矩阵。
-
int __set_legacy_tf(struct dc_transfer_func *func, const struct drm_color_lut *lut, uint32_t lut_size, bool has_rom)¶
计算传统传输函数
参数
struct dc_transfer_func *func
传输函数
const struct drm_color_lut *lut
定义颜色空间的查找表
uint32_t lut_size
相应查找表的大小
bool has_rom
如果可以使用 ROM 进行硬编码曲线
描述
仅适用于 sRGB 输入空间
返回
成功时为 0,失败时为 -ENOMEM
-
int __set_output_tf(struct dc_transfer_func *func, const struct drm_color_lut *lut, uint32_t lut_size, bool has_rom)¶
根据预期的输入空间计算输出传输函数。
参数
struct dc_transfer_func *func
传输函数
const struct drm_color_lut *lut
定义颜色空间的查找表
uint32_t lut_size
相应查找表的大小
bool has_rom
如果可以使用 ROM 进行硬编码曲线
返回
成功时为 0。失败时为 -ENOMEM。
-
int __set_input_tf(struct dc_color_caps *caps, struct dc_transfer_func *func, const struct drm_color_lut *lut, uint32_t lut_size)¶
根据预期的输入空间计算输入传输函数。
参数
struct dc_color_caps *caps
dc 颜色功能
struct dc_transfer_func *func
传输函数
const struct drm_color_lut *lut
定义颜色空间的查找表
uint32_t lut_size
相应查找表的大小。
返回
成功时为 0。失败时为 -ENOMEM。
-
int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev, struct drm_plane_state *plane_state)¶
验证是否支持 3D LUT,以及用户整形器和 3D LUT 是否与硬件支持的大小匹配
参数
struct amdgpu_device *adev
amdgpu 设备
struct drm_plane_state *plane_state
DRM 平面状态
描述
验证硬件(DCN 2.0 或更新版本)是否支持预混合 (DPP) 3D LUT,以及用户整形器和 3D LUT 是否与支持的大小匹配。
返回
成功时为 0。如果 LUT 大小无效,则为 -EINVAL。
-
int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state)¶
验证 DRM LUT 是否与硬件支持的大小匹配
参数
const struct drm_crtc_state *crtc_state
DRM CRTC 状态
描述
验证附加到 crtc_state
的 Degamma 和 Gamma LUT 是否为预期的大小。
返回
成功时为 0。如果任何 LUT 大小无效,则为 -EINVAL。
-
int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)¶
将 DRM 颜色管理映射到 DC 流。
参数
struct dm_crtc_state *crtc
amdgpu_dm crtc 状态
描述
在没有平面级颜色管理属性的情况下,我们可以自由使用任何硬件块,只要 CRTC CTM 始终在 CRTC RGM 之前,并在 CRTC DGM 之后即可。
如果 CRTC RGM 块是非线性的,则将其放置在 RGM LUT 块中。
如果 CRTC DGM 块是非线性的,则将其放置在 DGM LUT 块中。
如果 CRTC CTM 是非线性的,则将其放置在色域重映射块中。
RGM 块通常在所有 ASIC 中都具有更完整的功能和准确性 - DCE 不能支持自定义的非线性 CRTC DGM。
为了同时支持平面级颜色管理和 CRTC 级颜色管理,我们必须限制 CRTC 属性的使用或将调整混合在一起。
返回
成功时为 0。如果设置失败,则为错误代码。
-
int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, struct drm_plane_state *plane_state, struct dc_plane_state *dc_plane_state)¶
将 DRM 颜色管理映射到 DC 平面。
参数
struct dm_crtc_state *crtc
amdgpu_dm crtc 状态
struct drm_plane_state *plane_state
DRM 平面状态
struct dc_plane_state *dc_plane_state
目标 DC 表面
描述
更新底层 dc_stream_state 的输入传输函数 (ITF),以准备硬件提交。所使用的传输函数取决于为颜色管理在流上完成的准备工作。
返回
成功时为 0。如果内存分配失败,则为 -ENOMEM。
DCN 各代之间的 DC 颜色功能¶
DRM/KMS 框架定义了三个 CRTC 颜色校正属性:去伽马、颜色转换矩阵 (CTM) 和伽马,以及两个用于去伽马和伽马 LUT 大小的属性。AMD DC 在混合前编程一些颜色校正功能,但 DRM/KMS 没有每个平面的颜色校正属性。
一般来说,DRM CRTC 颜色属性按以下方式编程到 DC:混合后的 CRTC 伽马和混合前的 CRTC 去伽马。虽然 CTM 是在混合后编程的,但它被映射到 DPP 硬件块(混合前)。DRM 接口目前没有公开硬件中可用的其他颜色功能,因此会被绕过。
颜色管理功能(DPP 和 MPC)
Modules/color 计算各种颜色操作,这些操作被转换为抽象的硬件。DCE 5-12 几乎没有重要的更改,但从 DCN1 开始,每一代新产品的颜色管道都有相当大的差异。因此,我们抽象了颜色管道功能,以便 modules/DM 可以根据逻辑功能决定映射到硬件块。
-
struct rom_curve_caps¶
用于去伽马和重新伽马的预定义传输函数功能
定义:
struct rom_curve_caps {
uint16_t srgb : 1;
uint16_t bt2020 : 1;
uint16_t gamma2_2 : 1;
uint16_t pq : 1;
uint16_t hlg : 1;
};
成员
srgb
RGB 颜色空间传输函数
bt2020
BT.2020 传输函数
gamma2_2
标准伽马
pq
感知量化器传输函数
hlg
混合对数伽马传输函数
-
struct dpp_color_caps¶
显示管道和平面块的颜色管道功能
定义:
struct dpp_color_caps {
uint16_t dcn_arch : 1;
uint16_t input_lut_shared : 1;
uint16_t icsc : 1;
uint16_t dgam_ram : 1;
uint16_t post_csc : 1;
uint16_t gamma_corr : 1;
uint16_t hw_3d_lut : 1;
uint16_t ogam_ram : 1;
uint16_t ocsc : 1;
uint16_t dgam_rom_for_yuv : 1;
struct rom_curve_caps dgam_rom_caps;
struct rom_curve_caps ogam_rom_caps;
};
成员
dcn_arch
所有 DCE 代的处理方式相同
input_lut_shared
与 DGAM 共享。输入 LUT 与大多数 LUT 不同,只是普通的 256 条目查找
icsc
输入颜色空间转换
dgam_ram
可编程的去伽马 LUT
post_csc
颜色空间转换后,在色域重映射之前
gamma_corr
去伽马校正
hw_3d_lut
3D LUT 支持。它意味着之前有一个整形器 LUT。可以通过设置 mpc:shared_3d_lut 标志与 MPC 共享
ogam_ram
可编程的输出/混合伽马 LUT
ocsc
输出颜色空间转换
dgam_rom_for_yuv
YUV 平面的预定义反伽马 LUT
dgam_rom_caps
用于反伽马 1D LUT 的预定义曲线上限
ogam_rom_caps
用于重伽马 1D LUT 的预定义曲线上限
注意
hdr_mult 和色域重映射 (CTM) 在 DPP 中始终可用(按此顺序)
-
struct mpc_color_caps¶
用于多个管道和平面组合块的颜色管道能力
定义:
struct mpc_color_caps {
uint16_t gamut_remap : 1;
uint16_t ogam_ram : 1;
uint16_t ocsc : 1;
uint16_t num_3dluts : 3;
uint16_t shared_3d_lut:1;
struct rom_curve_caps ogam_rom_caps;
};
成员
gamut_remap
颜色变换矩阵
ogam_ram
可编程输出伽马 LUT
ocsc
输出颜色空间转换矩阵
num_3dluts
MPC 3D LUT;始终假定前面有一个整形器 LUT
shared_3d_lut
共享 3D LUT 标志。可以是 DPP 或 MPC,但只能有一个实例
ogam_rom_caps
用于重伽马 1D LUT 的预定义曲线上限
-
struct dc_color_caps¶
DPP 和 MPC 硬件块的颜色管道能力
定义:
struct dc_color_caps {
struct dpp_color_caps dpp;
struct mpc_color_caps mpc;
};
成员
dpp
DPP 的颜色管道上限
mpc
MPC 的颜色管道上限
-
enum pipe_split_policy¶
DCN 支持的管道拆分策略
常量
MPC_SPLIT_DYNAMIC
DC 将自动决定如何拆分管道,以在性能和功耗之间取得最佳平衡。这是建议的选项。
MPC_SPLIT_AVOID
避免管道拆分,这意味着 DC 不会尝试任何类型的拆分优化。
MPC_SPLIT_AVOID_MULT_DISP
使用此选项,DC 仅在使用单个显示器时尝试优化管道利用率;如果用户连接到第二个显示器,DC 将避免管道拆分。
描述
此枚举用于定义 DCN 支持的管道拆分策略。默认情况下,DC 倾向于 MPC_SPLIT_DYNAMIC。
-
struct dc_validation_set¶
用于存储用于验证的表面/流关联的结构
定义:
struct dc_validation_set {
struct dc_stream_state *stream;
struct dc_plane_state *plane_states[MAX_SURFACES];
uint8_t plane_count;
};
成员
stream
流状态属性
plane_states
表面状态
plane_count
活动平面的总数
颜色管道在 DCN 硬件世代之间经历了重大变化。在混合之前和之后可以执行哪些操作取决于硬件功能,如下面的 DCN 2.0 和 DCN 3.0 系列示意图所示。
DCN 2.0 系列颜色上限和映射
DCN 3.0 系列颜色上限和映射
混合模式属性¶
像素混合模式是 drm_plane
的 DRM 平面合成属性,用于描述如何将前景平面 (fg) 的像素与背景平面 (bg) 合成。在这里,我们介绍了 DRM 混合模式的主要概念,以帮助理解如何将此属性映射到 AMD DC 接口。有关此 DRM 属性和 alpha 混合方程的更多信息,请参阅 DRM 平面合成属性。
基本上,混合模式为平面合成设置 alpha 混合方程,该方程符合 alpha 通道影响像素颜色值状态的模式,从而影响生成的像素颜色。例如,考虑 alpha 混合方程的以下元素
fg.rgb:来自前景像素的每个 RGB 分量值。
fg.alpha:来自前景像素的 alpha 分量值。
bg.rgb:来自背景的每个 RGB 分量值。
plane_alpha:由平面“alpha”属性设置的平面 alpha 值,有关更多信息,请参阅 DRM 平面合成属性。
在基本的 alpha 混合方程中
out.rgb = alpha * fg.rgb + (1 - alpha) * bg.rgb
忽略平面中每个像素的 alpha 通道值,只有平面 alpha 会影响生成的像素颜色值。
DRM 有三种混合模式来定义平面合成中的混合公式
None:忽略像素 alpha 的混合公式。
预乘:假设平面中的像素颜色值在存储之前已由其自身的 alpha 通道预乘的混合公式。
覆盖:假设像素颜色值未与 alpha 通道值预乘的混合公式。
预乘是默认的像素混合模式,这意味着,当没有创建或定义混合模式属性时,DRM 认为平面的像素具有预乘的颜色值。在 IGT GPU 工具上,kms_plane_alpha_blend 测试提供了一组子测试来验证平面 alpha 和混合模式属性。
然后,AMDGPU 显示管理器 (DM) 将 DRM 混合模式及其元素映射到多管道/平面组合 (MPC) 的混合配置,如下所示
-
struct mpcc_blnd_cfg¶
MPCC 混合配置
定义:
struct mpcc_blnd_cfg {
struct tg_color black_color;
enum mpcc_alpha_blend_mode alpha_mode;
bool pre_multiplied_alpha;
int global_gain;
int global_alpha;
bool overlap_only;
int bottom_gain_mode;
int background_color_bpc;
int top_gain;
int bottom_inside_gain;
int bottom_outside_gain;
};
成员
black_color
背景颜色。
alpha_mode
alpha 混合模式 (MPCC_ALPHA_BLND_MODE)。
pre_multiplied_alpha
像素颜色值是否已由 alpha 通道预乘 (MPCC_ALPHA_MULTIPLIED_MODE)。
global_gain
当混合模式同时考虑像素 alpha 和平面时使用。
global_alpha
平面 alpha 值。
overlap_only
是否允许不同平面的重叠。
bottom_gain_mode
底部增益设置的混合模式。
background_color_bpc
bpc 的背景颜色。
top_gain
顶部增益设置。
bottom_inside_gain
底部内部的混合模式。
bottom_outside_gain
底部外部的混合模式。
因此,MPC 树上单个 MPCC 实例的混合配置由 mpcc_blnd_cfg
定义,其中 pre_multiplied_alpha
是用于设置 MPCC_ALPHA_MULTIPLIED_MODE
的 alpha 预乘模式标志。它控制是否乘以 alpha(真/假),仅当 DRM 预乘混合模式为真时。 mpcc_alpha_blend_mode
定义关于像素 alpha 和平面 alpha 值的 alpha 混合模式。它为 MPCC_ALPHA_BLND_MODE
设置以下三种模式之一,如下所述。
-
enum mpcc_alpha_blend_mode¶
定义关于像素 alpha 和平面 alpha 值的 alpha 混合模式
常量
MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA
使用 DPP alpha 值的每个像素 alpha
MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN
使用 DPP alpha 值乘以全局增益(平面 alpha)的每个像素 alpha
MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA
全局 alpha 值,忽略像素 alpha,仅考虑平面 alpha
然后,DM 将 enum mpcc_alpha_blend_mode
中的元素映射到 DRM 混合公式中的元素,如下所示
MPC 像素 alpha 与 DRM fg.alpha 匹配,作为来自平面的像素的 alpha 分量值
当应忽略像素 alpha 并且因此像素值未预乘时,MPC 全局 alpha 与 DRM plane_alpha 匹配
当 DRM fg.alpha 和 DRM plane_alpha 都参与混合方程时,MPC 全局增益 假定 MPC 全局 alpha 值
简而言之,通过选择 MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA
,将忽略 fg.alpha。另一方面,通过选择 MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN
,可以使用 (plane_alpha * fg.alpha) 分量。并且 MPCC_ALPHA_MULTIPLIED_MODE
定义像素颜色值是否乘以 alpha 预乘。
混合配置流程¶
通过以下路径从 DRM 配置到 DC 接口的 alpha 混合方程
更新
drm_plane_state
时,DM 调用amdgpu_dm_plane_fill_blending_from_plane_state()
,该函数将drm_plane_state
属性映射到dc_plane_info
结构,以便在操作系统无关组件 (DC) 中进行处理。在 DC 接口上,
struct mpcc_blnd_cfg
考虑到来自 DPP 的dc_plane_info
输入来编程 MPCC 混合配置。