feat: add displays info (#1052)

* test

* feat: dp info on amd

* chore: add other display types

* feat: use libdisplay-info, add screen size

* feat: add GUI

* feat: WIP nvidia

* feat: reuse display handle

* chore: clippy fixes

* chore: cleanup

* chore: make display-info an optional feature, add build dependency

* fix: ci

* fix ui imports

* fix: add new dependency to flatpak

* fix: add hwdata flatpak module
This commit is contained in:
Ilya Zlobintsev
2026-06-19 22:22:03 +03:00
committed by GitHub
parent 6c4e27d1d8
commit e2caa24ca8
39 changed files with 13648 additions and 90 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ runs:
- name: Install dependencies
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: libgtk-4-dev pkg-config libvulkan-dev libdrm-dev curl fuse3 libfuse-dev libadwaita-1-dev
packages: libgtk-4-dev pkg-config libvulkan-dev libdrm-dev curl fuse3 libfuse-dev libadwaita-1-dev libdisplay-info-dev
version: 1.1
- name: Update pci.ids
run: sudo curl -o /usr/share/hwdata/pci.ids https://pci-ids.ucw.cz/v2.2/pci.ids
Generated
+35
View File
@@ -1713,6 +1713,7 @@ dependencies = [
"jiff",
"lact-schema",
"libcopes",
"libdisplay-info",
"libdrm_amdgpu_sys",
"libflate",
"libloading",
@@ -1846,6 +1847,40 @@ dependencies = [
"log",
]
[[package]]
name = "libdisplay-info"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59fd96dbb2381ff31f314f07accbdf8550febdcc5cd8761ecaf7c1763361c359"
dependencies = [
"bitflags 2.11.1",
"libc",
"libdisplay-info-derive",
"libdisplay-info-sys",
"thiserror 2.0.18",
]
[[package]]
name = "libdisplay-info-derive"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8dc2c710cf5819e91220a446d9e64acc6814386cc22c509c3f0df83c0b874a98"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "libdisplay-info-sys"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26590d55b8819f9c6b0d95d9d12dc9edbfd1f2413e88814a33b631ac049bb51f"
dependencies = [
"semver",
"system-deps",
]
[[package]]
name = "libdrm_amdgpu_sys"
version = "0.8.16"
+3 -2
View File
@@ -197,6 +197,7 @@ Dependencies:
- make
- hwdata
- libdrm
- libdisplay-info
Optional Dependencies:
- vulkan-tools
@@ -205,9 +206,9 @@ Optional Dependencies:
Command to install all dependencies:
- Fedora:
`sudo dnf install rust cargo make git clang gtk4-devel libadwaita-devel libdrm-devel vulkan-tools clinfo`
`sudo dnf install rust cargo make git clang gtk4-devel libadwaita-devel libdrm-devel vulkan-tools libdisplay-info-devel clinfo`
- Arch:
`sudo pacman -S --needed base-devel git clang make rust gtk4 libadwaita hwdata vulkan-tools clinfo`
`sudo pacman -S --needed base-devel git clang make rust gtk4 libadwaita hwdata vulkan-tools clinfo libdisplay-info`
Steps:
+39
View File
@@ -2170,6 +2170,45 @@
"dest": "cargo/vendor/libcopes-1.0.0",
"dest-filename": ".cargo-checksum.json"
},
{
"type": "archive",
"archive-type": "tar-gzip",
"url": "https://static.crates.io/crates/libdisplay-info/libdisplay-info-0.3.0.crate",
"sha256": "59fd96dbb2381ff31f314f07accbdf8550febdcc5cd8761ecaf7c1763361c359",
"dest": "cargo/vendor/libdisplay-info-0.3.0"
},
{
"type": "inline",
"contents": "{\"package\": \"59fd96dbb2381ff31f314f07accbdf8550febdcc5cd8761ecaf7c1763361c359\", \"files\": {}}",
"dest": "cargo/vendor/libdisplay-info-0.3.0",
"dest-filename": ".cargo-checksum.json"
},
{
"type": "archive",
"archive-type": "tar-gzip",
"url": "https://static.crates.io/crates/libdisplay-info-derive/libdisplay-info-derive-0.1.1.crate",
"sha256": "8dc2c710cf5819e91220a446d9e64acc6814386cc22c509c3f0df83c0b874a98",
"dest": "cargo/vendor/libdisplay-info-derive-0.1.1"
},
{
"type": "inline",
"contents": "{\"package\": \"8dc2c710cf5819e91220a446d9e64acc6814386cc22c509c3f0df83c0b874a98\", \"files\": {}}",
"dest": "cargo/vendor/libdisplay-info-derive-0.1.1",
"dest-filename": ".cargo-checksum.json"
},
{
"type": "archive",
"archive-type": "tar-gzip",
"url": "https://static.crates.io/crates/libdisplay-info-sys/libdisplay-info-sys-0.3.0.crate",
"sha256": "26590d55b8819f9c6b0d95d9d12dc9edbfd1f2413e88814a33b631ac049bb51f",
"dest": "cargo/vendor/libdisplay-info-sys-0.3.0"
},
{
"type": "inline",
"contents": "{\"package\": \"26590d55b8819f9c6b0d95d9d12dc9edbfd1f2413e88814a33b631ac049bb51f\", \"files\": {}}",
"dest": "cargo/vendor/libdisplay-info-sys-0.3.0",
"dest-filename": ".cargo-checksum.json"
},
{
"type": "archive",
"archive-type": "tar-gzip",
@@ -107,6 +107,29 @@ modules:
strip-components: 0
sha256: 25856d4e64bb87de1f85af93b184a9d65177eacfde0ae4bad9a397797633c02b
- name: hwdata
config-opts:
- --datarootdir=/app/share
sources:
- type: git
url: https://github.com/vcrhonek/hwdata.git
tag: v0.408
commit: 4456b256a1a5b1d1c1c1a60a9f69c59f7743c522
x-checker-data:
type: git
- name: libdisplay-info
buildsystem: meson
sources:
- type: archive
url: https://gitlab.freedesktop.org/emersion/libdisplay-info/-/archive/0.3.0/libdisplay-info-0.3.0.tar.gz
sha256: 2b467e3336aec63819d6aca28d7310d3dc7415b2b3a3c3a5aec9d3727053c078
x-checker-data:
type: anitya
project-id: 326668
stable-only: true
url-template: https://gitlab.freedesktop.org/emersion/libdisplay-info/-/archive/$version/libdisplay-info-$version.tar.gz
- name: lact
buildsystem: simple
sources:
+2 -1
View File
@@ -4,7 +4,7 @@ mod macros;
pub use lact_schema as schema;
use lact_schema::{
DeviceApiInfo, ProcessList, ProfileRule,
DeviceApiInfo, DisplaysInfo, ProcessList, ProfileRule,
config::{GpuConfig, Profile, ProfileHooks},
};
@@ -155,6 +155,7 @@ impl DaemonClient {
request_with_id!(reset_pmfw, ResetPmfw, u64);
request_with_id!(dump_vbios, VbiosDump, Vec<u8>);
request_with_id!(get_process_list, ProcessList, ProcessList);
request_with_id!(get_displays_info, DisplaysInfo, DisplaysInfo);
pub async fn list_profiles(&self, include_state: bool) -> anyhow::Result<ProfilesInfo> {
self.make_request(Request::ListProfiles { include_state })
+3 -1
View File
@@ -4,9 +4,10 @@ version = "0.9.1"
edition.workspace = true
[features]
default = ["nvidia"]
default = ["nvidia", "display-info"]
bench = ["dep:divan"]
nvidia = []
display-info = ["dep:libdisplay-info"]
[dependencies]
lact-schema = { path = "../lact-schema" }
@@ -48,6 +49,7 @@ libcopes = "1.0.0"
libloading = "0.8.9" # Can be updated when https://github.com/rust-lang/rust-bindgen/issues/3332 is released
ureq = { version = "3.3.0", features = ["json", "rustls"] }
libdisplay-info = { version= "0.3.0", optional = true }
[dev-dependencies]
pretty_assertions = { workspace = true }
+6 -1
View File
@@ -1,8 +1,13 @@
#include "nvidia/kernel-open/common/inc/nv-ioctl-numbers.h"
#include "nvidia/nvapi/nvapi_lite_common.h"
#include "nvidia/src/common/sdk/nvidia/inc/class/cl0073.h"
#include "nvidia/src/common/sdk/nvidia/inc/class/cl0080.h"
#include "nvidia/src/common/sdk/nvidia/inc/class/cl2080.h"
#include "nvidia/src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073dp.h"
#include "nvidia/src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073system.h"
#include "nvidia/src/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080fb.h"
#include "nvidia/src/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gr.h"
#include "nvidia/src/common/sdk/nvidia/inc/nvos.h"
#include "nvidia/src/nvidia/arch/nvalloc/unix/include/nv_escape.h"
#include "nvidia/src/nvidia/arch/nvalloc/unix/include/nv_escape.h"
#include <stdint.h>
#include "nvidia/kernel-open/nvidia-drm/nv_drm_common_ioctl.h"
@@ -0,0 +1,586 @@
/*
* Copyright (c) 2015-2025, NVIDIA CORPORATION. All rights reserved.
*
* 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.
*/
#ifndef _NV_DRM_COMMON_IOCTL_H_
#define _NV_DRM_COMMON_IOCTL_H_
#include <drm/drm.h>
/*
* We should do our best to keep these values constant. Any change to these will
* be backwards incompatible with client applications that might be using them
*/
#define DRM_NVIDIA_GET_CRTC_CRC32 0x00
#define DRM_NVIDIA_GEM_IMPORT_NVKMS_MEMORY 0x01
#define DRM_NVIDIA_GEM_IMPORT_USERSPACE_MEMORY 0x02
#define DRM_NVIDIA_GET_DEV_INFO 0x03
#define DRM_NVIDIA_FENCE_SUPPORTED 0x04
#define DRM_NVIDIA_PRIME_FENCE_CONTEXT_CREATE 0x05
#define DRM_NVIDIA_GEM_PRIME_FENCE_ATTACH 0x06
#define DRM_NVIDIA_GET_CLIENT_CAPABILITY 0x08
#define DRM_NVIDIA_GEM_EXPORT_NVKMS_MEMORY 0x09
#define DRM_NVIDIA_GEM_MAP_OFFSET 0x0a
#define DRM_NVIDIA_GEM_ALLOC_NVKMS_MEMORY 0x0b
#define DRM_NVIDIA_GET_CRTC_CRC32_V2 0x0c
#define DRM_NVIDIA_GEM_EXPORT_DMABUF_MEMORY 0x0d
#define DRM_NVIDIA_GEM_IDENTIFY_OBJECT 0x0e
#define DRM_NVIDIA_DMABUF_SUPPORTED 0x0f
#define DRM_NVIDIA_GET_DPY_ID_FOR_CONNECTOR_ID 0x10
#define DRM_NVIDIA_GET_CONNECTOR_ID_FOR_DPY_ID 0x11
#define DRM_NVIDIA_GRANT_PERMISSIONS 0x12
#define DRM_NVIDIA_REVOKE_PERMISSIONS 0x13
#define DRM_NVIDIA_SEMSURF_FENCE_CTX_CREATE 0x14
#define DRM_NVIDIA_SEMSURF_FENCE_CREATE 0x15
#define DRM_NVIDIA_SEMSURF_FENCE_WAIT 0x16
#define DRM_NVIDIA_SEMSURF_FENCE_ATTACH 0x17
#define DRM_NVIDIA_GET_DRM_FILE_UNIQUE_ID 0x18
#define DRM_NVIDIA_REGISTER_ROI 0x19 /* Register ROI */
#define DRM_NVIDIA_UNREGISTER_ROI 0x1a /* Unregister ROI */
#define DRM_NVIDIA_GET_CRTC_ROI_CRCS 0x1b /* Read CRCs for registered ROIs */
#define DRM_NVIDIA_GET_ROI_CAPABILITIES 0x1c /* Get ROI related capabilities */
/* Maximum possible telltale CRCs per plane (used for array size)
* actual value is queried from the plane property NV_DRM_NUM_PLANE_TELLTALE_CRCS*/
#define NV_DRM_MAX_TELLTALES_PER_PLANE 64
/* Maximum possible ROIs per CRTC (used for array size)
* actual value is queried from DRM_NVIDIA_GET_ROI_CAPABILITIES */
#define NV_DRM_MAX_ROIS_PER_CRTC 64
/* IOCTLs */
#define DRM_IOCTL_NVIDIA_GEM_IMPORT_NVKMS_MEMORY \
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_GEM_IMPORT_NVKMS_MEMORY), \
struct drm_nvidia_gem_import_nvkms_memory_params)
#define DRM_IOCTL_NVIDIA_GEM_IMPORT_USERSPACE_MEMORY \
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_GEM_IMPORT_USERSPACE_MEMORY), \
struct drm_nvidia_gem_import_userspace_memory_params)
#define DRM_IOCTL_NVIDIA_GET_DEV_INFO \
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_GET_DEV_INFO), \
struct drm_nvidia_get_dev_info_params)
/*
* XXX Solaris compiler has issues with DRM_IO. None of this is supported on
* Solaris anyway, so just skip it.
*
* 'warning: suggest parentheses around arithmetic in operand of |'
*/
#if defined(NV_LINUX) || defined(NV_BSD)
#define DRM_IOCTL_NVIDIA_FENCE_SUPPORTED \
DRM_IO(DRM_COMMAND_BASE + DRM_NVIDIA_FENCE_SUPPORTED)
#define DRM_IOCTL_NVIDIA_DMABUF_SUPPORTED \
DRM_IO(DRM_COMMAND_BASE + DRM_NVIDIA_DMABUF_SUPPORTED)
#else
#define DRM_IOCTL_NVIDIA_FENCE_SUPPORTED 0
#define DRM_IOCTL_NVIDIA_DMABUF_SUPPORTED 0
#endif
#define DRM_IOCTL_NVIDIA_PRIME_FENCE_CONTEXT_CREATE \
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_PRIME_FENCE_CONTEXT_CREATE),\
struct drm_nvidia_prime_fence_context_create_params)
#define DRM_IOCTL_NVIDIA_GEM_PRIME_FENCE_ATTACH \
DRM_IOW((DRM_COMMAND_BASE + DRM_NVIDIA_GEM_PRIME_FENCE_ATTACH), \
struct drm_nvidia_gem_prime_fence_attach_params)
#define DRM_IOCTL_NVIDIA_GET_CLIENT_CAPABILITY \
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_GET_CLIENT_CAPABILITY), \
struct drm_nvidia_get_client_capability_params)
#define DRM_IOCTL_NVIDIA_GET_CRTC_CRC32 \
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_GET_CRTC_CRC32), \
struct drm_nvidia_get_crtc_crc32_params)
#define DRM_IOCTL_NVIDIA_GET_CRTC_CRC32_V2 \
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_GET_CRTC_CRC32_V2), \
struct drm_nvidia_get_crtc_crc32_v2_params)
#define DRM_IOCTL_NVIDIA_GEM_EXPORT_NVKMS_MEMORY \
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_GEM_EXPORT_NVKMS_MEMORY), \
struct drm_nvidia_gem_export_nvkms_memory_params)
#define DRM_IOCTL_NVIDIA_GEM_MAP_OFFSET \
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_GEM_MAP_OFFSET), \
struct drm_nvidia_gem_map_offset_params)
#define DRM_IOCTL_NVIDIA_GEM_ALLOC_NVKMS_MEMORY \
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_GEM_ALLOC_NVKMS_MEMORY), \
struct drm_nvidia_gem_alloc_nvkms_memory_params)
#define DRM_IOCTL_NVIDIA_GEM_EXPORT_DMABUF_MEMORY \
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_GEM_EXPORT_DMABUF_MEMORY), \
struct drm_nvidia_gem_export_dmabuf_memory_params)
#define DRM_IOCTL_NVIDIA_GEM_IDENTIFY_OBJECT \
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_GEM_IDENTIFY_OBJECT), \
struct drm_nvidia_gem_identify_object_params)
#define DRM_IOCTL_NVIDIA_GET_DPY_ID_FOR_CONNECTOR_ID \
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_GET_DPY_ID_FOR_CONNECTOR_ID),\
struct drm_nvidia_get_dpy_id_for_connector_id_params)
#define DRM_IOCTL_NVIDIA_GET_CONNECTOR_ID_FOR_DPY_ID \
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_GET_CONNECTOR_ID_FOR_DPY_ID),\
struct drm_nvidia_get_connector_id_for_dpy_id_params)
#define DRM_IOCTL_NVIDIA_GRANT_PERMISSIONS \
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_GRANT_PERMISSIONS), \
struct drm_nvidia_grant_permissions_params)
#define DRM_IOCTL_NVIDIA_REVOKE_PERMISSIONS \
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_REVOKE_PERMISSIONS), \
struct drm_nvidia_revoke_permissions_params)
#define DRM_IOCTL_NVIDIA_SEMSURF_FENCE_CTX_CREATE \
DRM_IOWR((DRM_COMMAND_BASE + \
DRM_NVIDIA_SEMSURF_FENCE_CTX_CREATE), \
struct drm_nvidia_semsurf_fence_ctx_create_params)
#define DRM_IOCTL_NVIDIA_SEMSURF_FENCE_CREATE \
DRM_IOWR((DRM_COMMAND_BASE + \
DRM_NVIDIA_SEMSURF_FENCE_CREATE), \
struct drm_nvidia_semsurf_fence_create_params)
#define DRM_IOCTL_NVIDIA_SEMSURF_FENCE_WAIT \
DRM_IOW((DRM_COMMAND_BASE + \
DRM_NVIDIA_SEMSURF_FENCE_WAIT), \
struct drm_nvidia_semsurf_fence_wait_params)
#define DRM_IOCTL_NVIDIA_SEMSURF_FENCE_ATTACH \
DRM_IOW((DRM_COMMAND_BASE + \
DRM_NVIDIA_SEMSURF_FENCE_ATTACH), \
struct drm_nvidia_semsurf_fence_attach_params)
#define DRM_IOCTL_NVIDIA_GET_DRM_FILE_UNIQUE_ID \
DRM_IOWR((DRM_COMMAND_BASE + \
DRM_NVIDIA_GET_DRM_FILE_UNIQUE_ID), \
struct drm_nvidia_get_drm_file_unique_id_params)
#define DRM_IOCTL_NVIDIA_REGISTER_ROI \
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_REGISTER_ROI), \
struct drm_nvidia_register_roi_params)
#define DRM_IOCTL_NVIDIA_UNREGISTER_ROI \
DRM_IOW((DRM_COMMAND_BASE + DRM_NVIDIA_UNREGISTER_ROI), \
struct drm_nvidia_unregister_roi_params)
#define DRM_IOCTL_NVIDIA_GET_CRTC_ROI_CRCS \
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_GET_CRTC_ROI_CRCS), \
struct drm_nvidia_read_crc_params)
#define DRM_IOCTL_NVIDIA_GET_ROI_CAPABILITIES \
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_GET_ROI_CAPABILITIES), \
struct drm_nvidia_get_roi_capabilities_params)
struct drm_nvidia_gem_import_nvkms_memory_params {
uint64_t mem_size; /* IN */
uint64_t nvkms_params_ptr; /* IN */
uint64_t nvkms_params_size; /* IN */
uint32_t handle; /* OUT */
uint32_t __pad;
};
struct drm_nvidia_gem_import_userspace_memory_params {
uint64_t size; /* IN Size of memory in bytes */
uint64_t address; /* IN Virtual address of userspace memory */
uint32_t handle; /* OUT Handle to gem object */
};
struct drm_nvidia_get_dev_info_params {
uint32_t gpu_id; /* OUT */
uint32_t mig_device; /* OUT */
uint32_t primary_index; /* OUT; the "card%d" value */
uint32_t supports_alloc; /* OUT */
/* The generic_page_kind, page_kind_generation, and sector_layout
* fields are only valid if supports_alloc is true.
* See DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D definitions of these. */
uint32_t generic_page_kind; /* OUT */
uint32_t page_kind_generation; /* OUT */
uint32_t sector_layout; /* OUT */
uint32_t supports_sync_fd; /* OUT */
uint32_t supports_semsurf; /* OUT */
};
struct drm_nvidia_prime_fence_context_create_params {
uint32_t handle; /* OUT GEM handle to fence context */
uint32_t index; /* IN Index of semaphore to use for fencing */
uint64_t size; /* IN Size of semaphore surface in bytes */
/* Params for importing userspace semaphore surface */
uint64_t import_mem_nvkms_params_ptr; /* IN */
uint64_t import_mem_nvkms_params_size; /* IN */
/* Params for creating software signaling event */
uint64_t event_nvkms_params_ptr; /* IN */
uint64_t event_nvkms_params_size; /* IN */
};
struct drm_nvidia_gem_prime_fence_attach_params {
uint32_t handle; /* IN GEM handle to attach fence to */
uint32_t fence_context_handle; /* IN GEM handle to fence context on which fence is run on */
uint32_t sem_thresh; /* IN Semaphore value to reach before signal */
uint32_t __pad;
};
struct drm_nvidia_get_client_capability_params {
uint64_t capability; /* IN Client capability enum */
uint64_t value; /* OUT Client capability value */
};
/* Struct that stores Crc value and if it is supported by hardware */
struct drm_nvidia_crtc_crc32 {
uint32_t value; /* Read value, undefined if supported is false */
uint8_t supported; /* Supported boolean, true if readable by hardware */
uint8_t __pad0;
uint16_t __pad1;
};
struct drm_nvidia_crtc_crc32_v2_out {
struct drm_nvidia_crtc_crc32 compositorCrc32; /* OUT compositor hardware CRC32 value */
struct drm_nvidia_crtc_crc32 rasterGeneratorCrc32; /* OUT raster generator CRC32 value */
struct drm_nvidia_crtc_crc32 outputCrc32; /* OUT SF/SOR CRC32 value */
};
struct drm_nvidia_get_crtc_crc32_v2_params {
uint32_t crtc_id; /* IN CRTC identifier */
struct drm_nvidia_crtc_crc32_v2_out crc32; /* OUT Crc32 output structure */
};
struct drm_nvidia_get_crtc_crc32_params {
uint32_t crtc_id; /* IN CRTC identifier */
uint32_t crc32; /* OUT CRC32 value */
};
struct drm_nvidia_gem_export_nvkms_memory_params {
uint32_t handle; /* IN */
uint32_t __pad;
uint64_t nvkms_params_ptr; /* IN */
uint64_t nvkms_params_size; /* IN */
};
struct drm_nvidia_gem_map_offset_params {
uint32_t handle; /* IN Handle to gem object */
uint32_t __pad;
uint64_t offset; /* OUT Fake offset */
};
#define NV_GEM_ALLOC_NO_SCANOUT (1 << 0)
struct drm_nvidia_gem_alloc_nvkms_memory_params {
uint32_t handle; /* OUT */
uint8_t block_linear; /* IN */
uint8_t compressible; /* IN/OUT */
uint16_t __pad0;
uint64_t memory_size; /* IN */
uint32_t flags; /* IN */
uint32_t __pad1;
};
struct drm_nvidia_gem_export_dmabuf_memory_params {
uint32_t handle; /* IN GEM Handle*/
uint32_t __pad;
uint64_t nvkms_params_ptr; /* IN */
uint64_t nvkms_params_size; /* IN */
};
typedef enum {
NV_GEM_OBJECT_NVKMS,
NV_GEM_OBJECT_DMABUF,
NV_GEM_OBJECT_USERMEMORY,
NV_GEM_OBJECT_UNKNOWN = 0x7fffffff /* Force size of 32-bits. */
} drm_nvidia_gem_object_type;
struct drm_nvidia_gem_identify_object_params {
uint32_t handle; /* IN GEM handle*/
drm_nvidia_gem_object_type object_type; /* OUT GEM object type */
};
struct drm_nvidia_get_dpy_id_for_connector_id_params {
uint32_t connectorId; /* IN */
uint32_t dpyId; /* OUT */
};
struct drm_nvidia_get_connector_id_for_dpy_id_params {
uint32_t dpyId; /* IN */
uint32_t connectorId; /* OUT */
};
enum drm_nvidia_permissions_type {
NV_DRM_PERMISSIONS_TYPE_MODESET = 2,
NV_DRM_PERMISSIONS_TYPE_SUB_OWNER = 3
};
struct drm_nvidia_grant_permissions_params {
int32_t fd; /* IN */
uint32_t dpyId; /* IN */
uint32_t type; /* IN */
};
struct drm_nvidia_revoke_permissions_params {
uint32_t dpyId; /* IN */
uint32_t type; /* IN */
};
struct drm_nvidia_semsurf_fence_ctx_create_params {
uint64_t index; /* IN Index of the desired semaphore in the
* fence context's semaphore surface */
/* Params for importing userspace semaphore surface */
uint64_t nvkms_params_ptr; /* IN */
uint64_t nvkms_params_size; /* IN */
uint32_t handle; /* OUT GEM handle to fence context */
uint32_t __pad;
};
struct drm_nvidia_semsurf_fence_create_params {
uint32_t fence_context_handle; /* IN GEM handle to fence context on which
* fence is run on */
uint32_t timeout_value_ms; /* IN Timeout value in ms for the fence
* after which the fence will be signaled
* with its error status set to -ETIMEDOUT.
* Default timeout value is 5000ms */
uint64_t wait_value; /* IN Semaphore value to reach before signal */
int32_t fd; /* OUT sync FD object representing the
* semaphore at the specified index reaching
* a value >= wait_value */
uint32_t __pad;
};
/*
* Note there is no provision for timeouts in this ioctl. The kernel
* documentation asserts timeouts should be handled by fence producers, and
* that waiters should not second-guess their logic, as it is producers rather
* than consumers that have better information when it comes to determining a
* reasonable timeout for a given workload.
*/
struct drm_nvidia_semsurf_fence_wait_params {
uint32_t fence_context_handle; /* IN GEM handle to fence context which will
* be used to wait on the sync FD. Need not
* be the fence context used to create the
* sync FD. */
int32_t fd; /* IN sync FD object to wait on */
uint64_t pre_wait_value; /* IN Wait for the semaphore represented by
* fence_context to reach this value before
* waiting for the sync file. */
uint64_t post_wait_value; /* IN Signal the semaphore represented by
* fence_context to this value after waiting
* for the sync file */
};
struct drm_nvidia_semsurf_fence_attach_params {
uint32_t handle; /* IN GEM handle of buffer */
uint32_t fence_context_handle; /* IN GEM handle of fence context */
uint32_t timeout_value_ms; /* IN Timeout value in ms for the fence
* after which the fence will be signaled
* with its error status set to -ETIMEDOUT.
* Default timeout value is 5000ms */
uint32_t shared; /* IN If true, fence will reserve shared
* access to the buffer, otherwise it will
* reserve exclusive access */
uint64_t wait_value; /* IN Semaphore value to reach before signal */
};
struct drm_nvidia_get_drm_file_unique_id_params {
uint64_t id; /* OUT Unique ID of the DRM file */
};
/**
* @brief Parameters for getting ROI capabilities
*
* This structure is used with the DRM_NVIDIA_GET_ROI_CAPABILITIES ioctl to
* get ROI related capabilities.
*
* @param[out] max_rois Maximum number of ROIs that can be registered
*/
struct drm_nvidia_get_roi_capabilities_params {
uint32_t max_registered_rois; /* OUT Maximum number of ROIs that can be registered */
uint32_t reserved[7];
};
/**
* @brief Rectangle structure for ROI
*
* This structure is used to define a rectangle region of interest.
*
* @param[in] x X coordinate of the top-left corner
* @param[in] y Y coordinate of the top-left corner
* @param[in] width Width of the ROI
* @param[in] height Height of the ROI
*/
struct drm_nvidia_roi_rect {
uint32_t x;
uint32_t y;
uint32_t width;
uint32_t height;
};
/**
* @brief Parameters for registering a Region of Interest (ROI)
*
* This structure is used to register an ROI region in the Region RAM which can
* then be referenced by its region handle when configuring a window to enable CRC.
* The region handle is treated as a separate resource and must be registered
* outside of the regular commit cycle.
*
* @param[in] rect Rectangle defining the ROI coordinates
* @param[out] region_handle Unique handle for the registered ROI
*/
struct drm_nvidia_register_roi_params {
struct drm_nvidia_roi_rect rect; /* IN */
uint64_t region_handle; /* OUT */
};
/**
* @brief Parameters for unregistering a Region of Interest (ROI)
*
* This structure is used to unregister a previously registered ROI region.
* Note: A region handle that is actively in use (configured in the CRC enablement
* property) cannot be unregistered. Only a handle that was previously registered
* by this client can be unregistered.
*
* @param[in] region_handle Handle of the ROI to unregister
*/
struct drm_nvidia_unregister_roi_params {
uint64_t region_handle; /* IN */
};
/**
* @brief Per-plane telltale CRC configuration
*
* This structure defines the configuration for telltale CRC on a per-plane basis.
* Each plane can have multiple telltale CRC regions configured, with each region
* referencing a previously registered ROI via its region handle.
*
* @param[in] region_handle Handle of registered ROI to use
* @param[in] golden_crc Expected CRC value for safety interrupts (0 if not configured)
*/
struct drm_nvidia_telltale_per_plane_config {
uint64_t region_handle; /* IN */
uint64_t golden_crc; /* IN */
};
/* NV_DRM_NUM_PLANE_TELLTALE_CRCS is a plane property that can be read to get
* the max number of telltale CRCs that can be enabled on a plane */
/**
* @brief Blob property structure for NV_DRM_PLANE_TELLTALES
*
* This structure is used as the content for the NV_DRM_PLANE_TELLTALES blob property
* that is set on a plane before atomic commit. It contains an array of telltale
* configurations, one for each telltale CRC region that should be enabled on the plane.
* The number of configurations should not exceed the value read from the
* NV_DRM_NUM_PLANE_TELLTALE_CRCS plane property.
* This property is expected to be set in the regular atomic commit operation.
*
* @param[in] telltale_configs Array of telltale CRC configurations
*/
struct drm_nvidia_plane_telltales {
struct drm_nvidia_telltale_per_plane_config \
telltale_configs[NV_DRM_MAX_TELLTALES_PER_PLANE]; /* IN */
};
/**
* @brief ROI CRC data structure
*
* This structure contains the CRC value for a specific ROI region. It is used
* as part of the array returned by the DRM_NVIDIA_GET_CRTC_ROI_CRCS ioctl to
* provide CRC values for all active ROI regions on a CRTC.
*
* @param[out] region_handle Handle of the ROI region
* @param[out] crc Computed CRC value for this ROI
* @param[in/out] reserved Reserved fields for future use
*/
struct drm_nvidia_roi_crc {
uint64_t region_handle; /* OUT */
uint64_t crc; /* OUT */
uint64_t reserved[4];
};
/**
* @brief Parameters for reading CRC data from CRTC
*
* This structure is used with the DRM_NVIDIA_GET_CRTC_ROI_CRCS ioctl to read
* the CRC values for all registered ROI regions that are currently active on
* the specified CRTC. The ioctl will populate the roi_crcs array with CRC data
* for each active region and set num_collected_crcs to indicate how many valid
* entries are in the array.
* Please note that only the last collected CRC is returned per active region handle.
*
* @param[in] crtc_id CRTC identifier to read CRCs from
* @param[out] num_collected_crcs Number of valid CRC entries returned
* @param[in/out] reserved Reserved fields for future use
* @param[out] roi_crcs Array of ROI CRC data
*/
struct drm_nvidia_read_crc_params {
int32_t crtc_id; /* IN */
int32_t num_collected_crcs; /* OUT */
struct drm_nvidia_roi_crc roi_crcs[NV_DRM_MAX_ROIS_PER_CRTC]; /* OUT */
uint64_t reserved[4];
};
/**
* @brief Named transfer function enum
*
* This enum defines the named transfer functions that can be used to set
* the degamma and regamma transfer functions properties.
*/
enum nv_drm_transfer_function {
NV_DRM_TRANSFER_FUNCTION_DEFAULT,
NV_DRM_TRANSFER_FUNCTION_LINEAR,
NV_DRM_TRANSFER_FUNCTION_PQ,
/*
* nvidia-drm only supports the transfer function types defined above. The
* below transfer functions are currently only supported by tegradisp-drm,
* and not by nvidia-drm. Do not define a transfer function above
* NV_DRM_TRANSFER_FUNCTION_SRGB without updating
* NV_DRM_TRANSFER_FUNCTION_MAX.
*/
NV_DRM_TRANSFER_FUNCTION_SRGB,
NV_DRM_TRANSFER_FUNCTION_SMPTE_170M,
NV_DRM_TRANSFER_FUNCTION_TEGRA_MAX,
NV_DRM_TRANSFER_FUNCTION_MAX = NV_DRM_TRANSFER_FUNCTION_SRGB,
};
#endif /* _NV_DRM_COMMON_IOCTL_H_ */
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2001-2021, NVIDIA CORPORATION. All rights reserved.
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
#ifndef _cl0073_h_
#define _cl0073_h_
#ifdef __cplusplus
extern "C" {
#endif
#include "nvtypes.h"
#define NV04_DISPLAY_COMMON (0x00000073)
/* event values */
#define NV0073_NOTIFIERS_SW (0)
#define NV0073_NOTIFIERS_LTM_CALC_TIMEOUT (5)
#define NV0073_NOTIFIERS_MAXCOUNT (6)
#define NV0073_NOTIFICATION_STATUS_IN_PROGRESS (0x8000)
#define NV0073_NOTIFICATION_STATUS_BAD_ARGUMENT (0x4000)
#define NV0073_NOTIFICATION_STATUS_ERROR_INVALID_STATE (0x2000)
#define NV0073_NOTIFICATION_STATUS_ERROR_STATE_IN_USE (0x1000)
#define NV0073_NOTIFICATION_STATUS_DONE_SUCCESS (0x0000)
/* pio method data structure */
typedef volatile struct _cl0073_tag0 {
NvV32 Reserved00[0x7c0];
} Nv073Typedef, Nv04DisplayCommon;
#define NV073_TYPEDEF Nv04DisplayCommon
#ifdef __cplusplus
}; /* extern "C" */
#endif
#endif /* _cl0073_h_ */
@@ -0,0 +1,61 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
#pragma once
//
// This file was generated with FINN, an NVIDIA coding tool.
// Source file: ctrl/ctrl0073/ctrl0073base.finn
//
#include "ctrl/ctrlxxxx.h"
/* NV04_DISPLAY_COMMON control commands and parameters */
#define NV0073_CTRL_CMD(cat,idx) NVXXXX_CTRL_CMD(0x0073, NV0073_CTRL_##cat, idx)
/* NV04_DISPLAY_COMMON command categories (6bits) */
#define NV0073_CTRL_RESERVED (0x00U)
#define NV0073_CTRL_SYSTEM (0x01U)
#define NV0073_CTRL_SPECIFIC (0x02U)
#define NV0073_CTRL_EVENT (0x03U)
#define NV0073_CTRL_INTERNAL (0x04U)
#define NV0073_CTRL_COMMON (0x05U)
#define NV0073_CTRL_DFP (0x11U)
#define NV0073_CTRL_DP (0x13U)
#define NV0073_CTRL_SVP (0x14U)
#define NV0073_CTRL_DPU (0x15U)
#define NV0073_CTRL_PSR (0x16U)
#define NV0073_CTRL_STEREO (0x17U)
/*
* NV0073_CTRL_CMD_NULL
*
* This command does nothing.
* This command does not take any parameters.
*
* Possible status values returned are:
* NV_OK
*/
#define NV0073_CTRL_CMD_NULL (0x730000U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_RESERVED_INTERFACE_ID << 8) | 0x0" */
/* _ctrl0073base_h_ */
@@ -0,0 +1,119 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
#pragma once
#include <nvtypes.h>
//
// This file was generated with FINN, an NVIDIA coding tool.
// Source file: ctrl/ctrl0073/ctrl0073common.finn
//
/*
* DSC caps -
* bDscSupported
* If GPU supports DSC or not
*
* encoderColorFormatMask
* Mask of all color formats for which DSC
* encoding is supported by GPU
*
* lineBufferSizeKB
* Size of line buffer.
*
* rateBufferSizeKB
* Size of rate buffer per slice.
*
* bitsPerPixelPrecision
* Bits per pixel precision for DSC e.g. 1/16, 1/8, 1/4, 1/2, 1bpp
*
* maxNumHztSlices
* Maximum number of horizontal slices supported by DSC encoder
*
* lineBufferBitDepth
* Bit depth used by the GPU to store the reconstructed pixels within
* the line buffer
*/
#define NV0073_CTRL_CMD_DSC_CAP_PARAMS_MESSAGE_ID (0x1U)
typedef struct NV0073_CTRL_CMD_DSC_CAP_PARAMS {
NvBool bDscSupported;
NvU32 encoderColorFormatMask;
NvU32 lineBufferSizeKB;
NvU32 rateBufferSizeKB;
NvU32 bitsPerPixelPrecision;
NvU32 maxNumHztSlices;
NvU32 lineBufferBitDepth;
} NV0073_CTRL_CMD_DSC_CAP_PARAMS;
/*
* NV0073_CTRL_CMD_FRL_CONFIG_MACRO_PAD
*
* subDeviceInstance
* This parameter specifies the subdevice instance within the
* NV04_DISPLAY_COMMON parent device to which the operation should be
* directed. This parameter must specify a value between zero and the
* total number of subdevices within the parent device. This parameter
* should be set to zero for default behavior
* cmd
* This parameter is an input to this command.
* Here are the current defined fields:
* NV0073_CTRL_CMD_FRL_CONFIG_MACRO_PAD_CMD_POWER
* Set to specify what operation to run.
* NV0073_CTRL_CMD_FRL_CONFIG_MACRO_PAD_CMD_POWER_UP
* Request to power up pad.
* NV0073_CTRL_CMD_FRL_CONFIG_MACRO_PAD_CMD_POWER_DOWN
* Request to power down the pad.
* linkBw
* This parameter is used to pass in the link bandwidth required to run the
* power up sequence. Refer enum DM_FRL_LINK_RATE_GBPS for valid values.
* laneCount
* This parameter is used to pass the lanecount.
* sorIndex
* This parameter is used to pass the SOR index.
* padlinkIndex
* This parameter is used to pass the padlink index for primary link.
* Please refer enum DFPPADLINK for valid index values for Link A~F.
*/
#define NV0073_CTRL_CMD_FRL_CONFIG_MACRO_PAD (0x730502U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_COMMON_INTERFACE_ID << 8) | NV0073_CTRL_CMD_FRL_CONFIG_MACRO_PAD_PARAMS_MESSAGE_ID" */
#define NV0073_CTRL_CMD_FRL_CONFIG_MACRO_PAD_PARAMS_MESSAGE_ID (0x2U)
typedef struct NV0073_CTRL_CMD_FRL_CONFIG_MACRO_PAD_PARAMS {
NvU32 subDeviceInstance;
NvU32 cmd;
NvU32 linkBw;
NvU32 laneCount;
NvU32 sorIndex;
NvU32 padlinkIndex;
} NV0073_CTRL_CMD_FRL_CONFIG_MACRO_PAD_PARAMS;
#define NV0073_CTRL_CMD_FRL_CONFIG_MACRO_PAD_CMD_POWER 0:0
#define NV0073_CTRL_CMD_FRL_CONFIG_MACRO_PAD_CMD_POWER_UP (0x00000000U)
#define NV0073_CTRL_CMD_FRL_CONFIG_MACRO_PAD_CMD_POWER_DOWN (0x00000001U)
/* _ctrl0073common_h_ */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,32 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2011-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
#pragma once
#include <nvtypes.h>
//
// This file was generated with FINN, an NVIDIA coding tool.
// Source file: ctrl/ctrl0073/ctrl0073dpu.finn
//
@@ -0,0 +1,112 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2009-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
#pragma once
#include <nvtypes.h>
//
// This file was generated with FINN, an NVIDIA coding tool.
// Source file: ctrl/ctrl0073/ctrl0073event.finn
//
#include "ctrl/ctrl0073/ctrl0073base.h"
/*
* tilemask
* Tiles assocaited with calc tiemout head.
* frameActive
* New frame has started on this Head.
* histoReady
* Asserts when histogram data from all the "enabled" LTMs belonging to this head
* is ready.
* startFrameReady
* When histo_ready interrupt
* is received and HDMA is programmed and then RISCV asserts STARTFRAME_READY.
*/
typedef struct NV0073_LTM_HEAD_STATUS_PARAMS {
NvU8 tileMask;
NvBool frameActive;
NvBool histoReady;
NvBool startFrameReady;
} NV0073_LTM_HEAD_STATUS_PARAMS;
/* NV04_DISPLAY_COMMON event-related control commands and parameters */
/*
* NV0073_CTRL_CMD_EVENT_SET_NOTIFICATION
*
* This command sets event notification state for the associated display
* object. This command requires that an instance of NV01_EVENT has been
* previously bound to the associated display object.
*
* subDeviceInstance
* This parameter specifies the subdevice instance within the
* NV04_DISPLAY_COMMON parent device to which the operation should be
* directed. This parameter must specify a value between zero and the
* total number of subdevices within the parent device. This parameter
* should be set to zero for default behavior.
* hEvent
* This parameter specifies the handle of the NV01_EVENT instance
* to be bound to the given subDeviceInstance.
* event
* This parameter specifies the type of event to which the specified
* action is to be applied. This parameter must specify a valid
* NV0073_NOTIFIERS value (see cl0073.h for more details) and should
* not exceed one less NV0073_NOTIFIERS_MAXCOUNT.
* action
* This parameter specifies the desired event notification action.
* Valid notification actions include:
* NV0073_CTRL_SET_EVENT_NOTIFICATION_DISABLE
* This action disables event notification for the specified
* event for the associated subdevice object.
* NV0073_CTRL_SET_EVENT_NOTIFICATION_SINGLE
* This action enables single-shot event notification for the
* specified event for the associated subdevice object.
* NV0073_CTRL_SET_EVENT_NOTIFICATION_REPEAT
* This action enables repeated event notification for the specified
* event for the associated system controller object.
*
* Possible status values returned are:
* NV_OK
* NV_ERR_INVALID_PARAM_STRUCT
* NV_ERR_INVALID_ARGUMENT
* NV_ERR_INVALID_STATE
*/
#define NV0073_CTRL_CMD_EVENT_SET_NOTIFICATION (0x730301U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_EVENT_INTERFACE_ID << 8) | NV0073_CTRL_EVENT_SET_NOTIFICATION_PARAMS_MESSAGE_ID" */
#define NV0073_CTRL_EVENT_SET_NOTIFICATION_PARAMS_MESSAGE_ID (0x1U)
typedef struct NV0073_CTRL_EVENT_SET_NOTIFICATION_PARAMS {
NvU32 subDeviceInstance;
NvHandle hEvent;
NvU32 event;
NvU32 action;
} NV0073_CTRL_EVENT_SET_NOTIFICATION_PARAMS;
/* valid action values */
#define NV0073_CTRL_EVENT_SET_NOTIFICATION_ACTION_DISABLE (0x00000000U)
#define NV0073_CTRL_EVENT_SET_NOTIFICATION_ACTION_SINGLE (0x00000001U)
#define NV0073_CTRL_EVENT_SET_NOTIFICATION_ACTION_REPEAT (0x00000002U)
/* _ctrl0073event_h_ */
@@ -0,0 +1,59 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
#pragma once
//
// This file was generated with FINN, an NVIDIA coding tool.
// Source file: ctrl/ctrl0073/ctrl0073internal.finn
//
#include "ctrl/ctrl0073/ctrl0073base.h"
#include "ctrl/ctrl0073/ctrl0073system.h"
#include "ctrl/ctrl0073/ctrl0073dfp.h"
#define NV0073_CTRL_CMD_INTERNAL_GET_HOTPLUG_UNPLUG_STATE (0x730401U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_INTERNAL_INTERFACE_ID << 8) | NV0073_CTRL_INTERNAL_GET_HOTPLUG_UNPLUG_STATE_PARAMS_MESSAGE_ID" */
#define NV0073_CTRL_INTERNAL_GET_HOTPLUG_UNPLUG_STATE_PARAMS_MESSAGE_ID (0x1U)
typedef NV0073_CTRL_SYSTEM_GET_HOTPLUG_UNPLUG_STATE_PARAMS NV0073_CTRL_INTERNAL_GET_HOTPLUG_UNPLUG_STATE_PARAMS;
#define NV0073_CTRL_CMD_INTERNAL_VRR_SET_RGLINE_ACTIVE (0x730402U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_INTERNAL_INTERFACE_ID << 8) | NV0073_CTRL_CMD_INTERNAL_VRR_SET_RGLINE_ACTIVE_PARAMS_MESSAGE_ID" */
#define NV0073_CTRL_CMD_INTERNAL_VRR_SET_RGLINE_ACTIVE_PARAMS_MESSAGE_ID (0x2U)
typedef NV0073_CTRL_CMD_SYSTEM_VRR_SET_RGLINE_ACTIVE_PARAMS NV0073_CTRL_CMD_INTERNAL_VRR_SET_RGLINE_ACTIVE_PARAMS;
#define NV0073_CTRL_CMD_INTERNAL_DFP_SWITCH_DISP_MUX (0x730460U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_INTERNAL_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DFP_SWITCH_DISP_MUX_PARAMS_MESSAGE_ID" */
#define NV0073_CTRL_CMD_INTERNAL_DFP_SWITCH_DISP_MUX_PARAMS_MESSAGE_ID (0x3U)
typedef NV0073_CTRL_CMD_DFP_SWITCH_DISP_MUX_PARAMS NV0073_CTRL_CMD_INTERNAL_DFP_SWITCH_DISP_MUX_PARAMS;
#define NV0073_CTRL_CMD_INTERNAL_DFP_GET_DISP_MUX_STATUS (0x730404U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_INTERNAL_INTERFACE_ID << 8) | NV0073_CTRL_CMD_INTERNAL_DFP_GET_DISP_MUX_STATUS_PARAMS_MESSAGE_ID" */
#define NV0073_CTRL_CMD_INTERNAL_DFP_GET_DISP_MUX_STATUS_PARAMS_MESSAGE_ID (0x4U)
typedef NV0073_CTRL_CMD_DFP_GET_DISP_MUX_STATUS_PARAMS NV0073_CTRL_CMD_INTERNAL_DFP_GET_DISP_MUX_STATUS_PARAMS;
/* ctrl0073internal_h */
@@ -0,0 +1,70 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2012-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
#pragma once
#include <nvtypes.h>
//
// This file was generated with FINN, an NVIDIA coding tool.
// Source file: ctrl/ctrl0073/ctrl0073psr.finn
//
#include "ctrl/ctrl0073/ctrl0073base.h"
/* NV04_DISPLAY_COMMON psr-display-specific control commands and parameters */
/*
* NV0073_CTRL_CMD_PSR_GET_SR_PANEL_INFO
*
* displayId
* Display ID on which this information is being requested.
* frameLockPin
* Returns the frame lock pin of the panel.
* i2cAddress
* Returns the i2c address on which the SR panel is attached.
* NOTE: applies only to LVDS panels, otherwise this field
* should be ignored.
* bSelfRefreshEnabled
* Returns whether SR is enabled in RM.
*
* Possible status values returned are:
* NV_OK
* NV_ERR_INVALID_ARGUMENT
* NV_ERR_NOT_SUPPORTED
*/
#define NV0073_CTRL_CMD_PSR_GET_SR_PANEL_INFO (0x731602U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_PSR_INTERFACE_ID << 8) | NV0073_CTRL_PSR_GET_SR_PANEL_INFO_PARAMS_MESSAGE_ID" */
#define NV0073_CTRL_PSR_GET_SR_PANEL_INFO_PARAMS_MESSAGE_ID (0x2U)
typedef struct NV0073_CTRL_PSR_GET_SR_PANEL_INFO_PARAMS {
NvU32 displayId;
NvU32 frameLockPin;
NvU8 i2cAddress;
NvBool bSelfRefreshEnabled;
} NV0073_CTRL_PSR_GET_SR_PANEL_INFO_PARAMS;
/* _ctrl0073psr_h_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,201 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2015-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
#pragma once
#include <nvtypes.h>
//
// This file was generated with FINN, an NVIDIA coding tool.
// Source file: ctrl/ctrl0073/ctrl0073stereo.finn
//
#include "ctrl/ctrl0073/ctrl0073base.h"
/*
* NV0073_CTRL_CMD_STEREO_DONGLE_SUPPORTED
*
* This command returns the support status of the NV stereo emitter
* (also known as the stereo dongle). It reports if the stereo dongle
* is present in terms of the USB interface initialized in Resman.
* This provides a RmControl interface to the STEREO_DONGLE_SUPPORTED
* command in stereoDongleControl.
*
* Parameters:
* [IN] subDeviceInstance - This parameter specifies the subdevice instance
* within the NV04_DISPLAY_COMMON parent device to which the operation
* should be directed. This parameter must specify a value between
* zero and the total number of subdevices within the parent device.
* This parameter should be set to zero for default behavior.
* [IN] head - head to be passed to stereoDongleControl
* [IN] bI2cEmitter - I2C driven DT embedded emitter
* [IN] bForcedSupported - GPIO23 driven emitter
* [OUT] support - the control word returned by stereoDongleControl
*
* Possible status values returned are:
* NV_ERR_NOT_SUPPORTED - stereo is not initialized on the GPU
*/
#define NV0073_CTRL_CMD_STEREO_DONGLE_SUPPORTED (0x731702U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_STEREO_INTERFACE_ID << 8) | NV0073_CTRL_STEREO_DONGLE_SUPPORTED_PARAMS_MESSAGE_ID" */
#define NV0073_CTRL_STEREO_DONGLE_SUPPORTED_PARAMS_MESSAGE_ID (0x2U)
typedef struct NV0073_CTRL_STEREO_DONGLE_SUPPORTED_PARAMS {
NvU32 subDeviceInstance;
NvU32 head;
NvBool bI2cEmitter;
NvBool bForcedSupported;
NvU32 support;
} NV0073_CTRL_STEREO_DONGLE_SUPPORTED_PARAMS;
/*
* NV0073_CTRL_CMD_STEREO_DONGLE_SET_TIMINGS
*
* Sets new video mode timings
* E.g. from display driver on mode set
*
* Parameters:
* [IN] subDeviceInstance - This parameter specifies the subdevice instance
* within the NV04_DISPLAY_COMMON parent device to which the operation
* should be directed. This parameter must specify a value between
* zero and the total number of subdevices within the parent device.
* This parameter should be set to zero for default behavior.
* [IN] head - head to be passed to stereoDongleControl
* [IN] timings - new timings to be set
*
* Possible status values returned are:
* NV_OK
* NV_ERR_INVALID_ARGUMENT
* NV_ERR_NOT_SUPPORTED - stereo is not initialized on the GPU
*/
#define NV0073_CTRL_CMD_STEREO_DONGLE_SET_TIMINGS (0x731703U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_STEREO_INTERFACE_ID << 8) | NV0073_CTRL_STEREO_DONGLE_SET_TIMINGS_PARAMS_MESSAGE_ID" */
typedef struct NV0073_CTRL_STEREO_VIDEO_MODE_TIMINGS {
NvU32 PixelClock;
NvU16 TotalWidth;
NvU16 VisibleImageWidth;
NvU16 HorizontalBlankStart;
NvU16 HorizontalBlankWidth;
NvU16 HorizontalSyncStart;
NvU16 HorizontalSyncWidth;
NvU16 TotalHeight;
NvU16 VisibleImageHeight;
NvU16 VerticalBlankStart;
NvU16 VerticalBlankHeight;
NvU16 VerticalSyncStart;
NvU16 VerticalSyncHeight;
NvU16 InterlacedMode;
NvU16 DoubleScanMode;
NvU16 MonitorVendorId;
NvU16 MonitorProductId;
} NV0073_CTRL_STEREO_VIDEO_MODE_TIMINGS;
#define NV0073_CTRL_STEREO_DONGLE_SET_TIMINGS_PARAMS_MESSAGE_ID (0x3U)
typedef struct NV0073_CTRL_STEREO_DONGLE_SET_TIMINGS_PARAMS {
NvU32 subDeviceInstance;
NvU32 head;
NV0073_CTRL_STEREO_VIDEO_MODE_TIMINGS timings;
} NV0073_CTRL_STEREO_DONGLE_SET_TIMINGS_PARAMS;
/*
* NV0073_CTRL_CMD_STEREO_DONGLE_ACTIVATE
*
* stereoDongleActivate wrapper / NV_STEREO_DONGLE_ACTIVATE_DATA_ACTIVE_YES
* Updates sbios of 3D stereo state active
*
* Parameters:
* [IN] subDeviceInstance - This parameter specifies the subdevice instance
* within the NV04_DISPLAY_COMMON parent device to which the operation
* should be directed. This parameter must specify a value between
* zero and the total number of subdevices within the parent device.
* This parameter should be set to zero for default behavior.
* [IN] head - head to be passed to stereoDongleActivate
* [IN] bSDA - enable stereo on DDC SDA
* [IN] bWorkStation - is workstation stereo?
* [IN] bDLP - is checkerboard DLP Stereo?
* [IN] IRPower - IR power value
* [IN] flywheel - FlyWheel value
* [IN] bRegIgnore - use reg?
* [IN] bI2cEmitter - Sets NV_STEREO_DONGLE_ACTVATE_DATA_I2C_EMITTER_YES and pStereo->bAegisDT
* [IN] bForcedSupported - Sets NV_STEREO_DONGLE_FORCED_SUPPORTED_YES and pStereo->GPIOControlledDongle
* [IN] bInfoFrame - Aegis DT with DP InfoFrame
*
* Possible status values returned are:
* NV_OK
* NV_ERR_INVALID_ARGUMENT - if (head > OBJ_MAX_HEADS)
* NV_ERR_NOT_SUPPORTED - stereo is not initialized on the GPU
*/
#define NV0073_CTRL_CMD_STEREO_DONGLE_ACTIVATE (0x731704U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_STEREO_INTERFACE_ID << 8) | NV0073_CTRL_STEREO_DONGLE_ACTIVATE_PARAMS_MESSAGE_ID" */
#define NV0073_CTRL_STEREO_DONGLE_ACTIVATE_PARAMS_MESSAGE_ID (0x4U)
typedef struct NV0073_CTRL_STEREO_DONGLE_ACTIVATE_PARAMS {
NvU32 subDeviceInstance;
NvU32 head;
NvBool bSDA;
NvBool bWorkStation;
NvBool bDLP;
NvU8 IRPower;
NvU8 flywheel;
NvBool bRegIgnore;
NvBool bI2cEmitter;
NvBool bForcedSupported;
NvBool bInfoFrame;
} NV0073_CTRL_STEREO_DONGLE_ACTIVATE_PARAMS;
/*
* NV0073_CTRL_CMD_STEREO_DONGLE_DEACTIVATE
*
* stereoDongleActivate wrapper / NV_STEREO_DONGLE_ACTIVATE_DATA_ACTIVE_NO
*
* If active count<=0 then no 3D app is running which indicates
* that we have really deactivated the stereo, updates sbios of 3D stereo state NOT ACTIVE.
*
* Parameters:
* [IN] subDeviceInstance - This parameter specifies the subdevice instance
* within the NV04_DISPLAY_COMMON parent device to which the operation
* should be directed. This parameter must specify a value between
* zero and the total number of subdevices within the parent device.
* This parameter should be set to zero for default behavior.
* [IN] head - head to be passed to stereoDongleActivate
*
* Possible status values returned are:
* NV_OK
* NV_ERR_INVALID_ARGUMENT - if (head > OBJ_MAX_HEADS)
* NV_ERR_NOT_SUPPORTED - stereo is not initialized on the GPU
*/
#define NV0073_CTRL_CMD_STEREO_DONGLE_DEACTIVATE (0x731705U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_STEREO_INTERFACE_ID << 8) | NV0073_CTRL_STEREO_DONGLE_DEACTIVATE_PARAMS_MESSAGE_ID" */
#define NV0073_CTRL_STEREO_DONGLE_DEACTIVATE_PARAMS_MESSAGE_ID (0x5U)
typedef struct NV0073_CTRL_STEREO_DONGLE_DEACTIVATE_PARAMS {
NvU32 subDeviceInstance;
NvU32 head;
} NV0073_CTRL_STEREO_DONGLE_DEACTIVATE_PARAMS;
/* _ctrl0073stereo_h_ */
@@ -0,0 +1,32 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2010-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
#pragma once
#include <nvtypes.h>
//
// This file was generated with FINN, an NVIDIA coding tool.
// Source file: ctrl/ctrl0073/ctrl0073svp.finn
//
File diff suppressed because it is too large Load Diff
+3
View File
@@ -1,3 +1,5 @@
#[cfg(feature = "display-info")]
mod display;
pub mod gpu_controller;
pub mod handler;
mod metrics;
@@ -164,6 +166,7 @@ async fn handle_request<'a>(
Request::DeviceApiInfo { id } => ok_response(handler.get_device_api_info(id).await?),
Request::DeviceStats { id } => ok_response(handler.get_gpu_stats(id).await?),
Request::DeviceClocksInfo { id } => ok_response(handler.get_clocks_info(id).await?),
Request::DisplaysInfo { id } => ok_response(handler.get_displays_info(id).await?),
Request::DevicePowerProfileModes { id } => {
ok_response(handler.get_power_profile_modes(id).await?)
}
+130
View File
@@ -0,0 +1,130 @@
use anyhow::Context;
use lact_schema::{DisplayConnector, DisplayInfo, DisplayManufactureDate, DisplaysInfo};
use std::{collections::BTreeMap, fs, path::Path};
use tracing::warn;
const BASE_RATE_MULTIPLIER: u32 = 270;
const UHBR_RATE_MULTIPLIER: u32 = 10;
const UHBR_RATE_THRESHOLD: u32 = 1000;
pub fn get_base_displays_info(device_path: &Path) -> anyhow::Result<DisplaysInfo> {
let path_parent = device_path.parent().context("Invalid path")?;
let card_entry_name = path_parent
.file_name()
.and_then(|name| name.to_str())
.context("Invalid path")?;
let entries = fs::read_dir(path_parent)?;
let mut displays = BTreeMap::new();
for entry in entries {
let entry = entry?;
let display_entry_path = entry.path();
if display_entry_path
.file_name()
.and_then(|name| name.to_str())
.is_some_and(|name| name.starts_with(card_entry_name))
{
let status_path = display_entry_path.join("status");
if !status_path.exists() {
continue;
}
match fs::read_to_string(&status_path) {
Ok(status) if status.trim_ascii() == "connected" => {
match get_display_entry(&display_entry_path) {
Ok((key, info)) => {
displays.insert(key, info);
}
Err(err) => {
warn!(
"could not parse display info at {}: {err:#}",
display_entry_path.display()
);
}
}
}
Ok(_) => (),
Err(err) => warn!(
"could not read display status from {}: {err}",
status_path.display()
),
}
}
}
Ok(DisplaysInfo { displays })
}
fn get_display_entry(path: &Path) -> anyhow::Result<(String, DisplayInfo)> {
let edid_data = fs::read(path.join("edid")).context("Could not read edid")?;
let info =
libdisplay_info::info::Info::parse_edid(&edid_data).context("Could not parse edid")?;
let edid = info.edid().context("Missing edid in parsed info")?;
let connector_id = fs::read_to_string(path.join("connector_id"))
.context("Could not read connector_id")?
.trim_ascii()
.parse()
.context("Invalid connector_id")?;
let (_, connector) = path
.file_name()
.and_then(|name| name.to_str())
.and_then(|part| part.split_once('-'))
.with_context(|| format!("Unexpected display connector path {}", path.display()))?;
let connector_type = match connector
.split_once('-')
.context("Unexpected connector name")?
.0
{
"DP" => DisplayConnector::DisplayPort {
lanes: 0,
bandwidth: 0,
embedded: false,
},
"eDP" => DisplayConnector::DisplayPort {
lanes: 0,
bandwidth: 0,
embedded: true,
},
"HDMI" => DisplayConnector::Hdmi,
"DVI" => DisplayConnector::Dvi,
"VGA" => DisplayConnector::Vga,
_ => DisplayConnector::Other,
};
let info = DisplayInfo {
model: info.model(),
manufacturer: info.make(),
product_code: edid.vendor_product().product,
manufacture_date: Some(DisplayManufactureDate {
year: edid.vendor_product().manufacture_year.try_into()?,
week: edid.vendor_product().manufacture_week.try_into()?,
}),
#[allow(clippy::cast_sign_loss)]
size: edid
.screen_size()
.width_cm
.zip(edid.screen_size().height_cm)
.map(|(width, height)| (width as u32, height as u32)),
connector_type,
connector_id,
};
Ok((connector.to_owned(), info))
}
pub fn dp_rate_to_bandwidth(value: u32) -> u32 {
// Ref: https://elixir.bootlin.com/linux/v7.0.10/source/drivers/gpu/drm/amd/display/dc/dc_dp_types.h#L41
// Applies not only to AMD, as this is from the DP spec
// Values are for conversion to Mbps
if value < UHBR_RATE_THRESHOLD {
value * BASE_RATE_MULTIPLIER
} else {
value * UHBR_RATE_MULTIPLIER
}
}
+5
View File
@@ -97,6 +97,11 @@ pub trait GpuController {
fn vbios_dump(&self) -> anyhow::Result<Vec<u8>>;
fn process_list(&self) -> anyhow::Result<ProcessList>;
#[cfg(feature = "display-info")]
fn populate_displays_info(&self, _info: &mut lact_schema::DisplaysInfo) -> anyhow::Result<()> {
Ok(())
}
}
#[derive(Clone, Debug)]
@@ -24,6 +24,8 @@ use lact_schema::{
VramStats,
config::{ClocksConfiguration, FanControlSettings, FanCurve, GpuConfig},
};
#[cfg(feature = "display-info")]
use lact_schema::{DisplayConnector, DisplaysInfo};
use libdrm_amdgpu_sys::AMDGPU::{GpuMetrics, HW_IP::HW_IP_TYPE, ThrottlerBit, ThrottlerType};
use libdrm_amdgpu_sys::{AMDGPU::SENSOR_INFO::SENSOR_TYPE, LibDrmAmdgpu, PCI};
use std::{
@@ -1417,6 +1419,42 @@ impl GpuController for AmdGpuController {
&mut last_total_time_map,
)
}
#[cfg(feature = "display-info")]
fn populate_displays_info(&self, info: &mut DisplaysInfo) -> anyhow::Result<()> {
let debugfs = self.debugfs_path().context("Could not get debugfs")?;
for (connector, info) in &mut info.displays {
if let DisplayConnector::DisplayPort {
lanes,
bandwidth,
embedded: _,
} = &mut info.connector_type
{
let link_settings_path = debugfs.join(connector).join("link_settings");
let link_settings = fs::read_to_string(link_settings_path)?;
let mut parts = link_settings.split_ascii_whitespace().skip(1);
*lanes = parts
.next()
.context("Missing lane count")?
.parse::<u16>()
.context("Invalid lane count")?;
let bw_enum = parts
.next()
.context("Missing bandwidth")?
.strip_prefix("0x")
.and_then(|value| u32::from_str_radix(value, 16).ok())
.context("Invalid bandwidth value")?;
*bandwidth = crate::server::display::dp_rate_to_bandwidth(bw_enum);
}
}
Ok(())
}
}
#[cfg(not(test))]
@@ -1265,4 +1265,52 @@ impl GpuController for NvidiaGpuController {
supported_util_types: SUPPORTED_UTIL_TYPES.iter().copied().collect(),
})
}
#[cfg(feature = "display-info")]
fn populate_displays_info(&self, info: &mut lact_schema::DisplaysInfo) -> anyhow::Result<()> {
use lact_schema::DisplayConnector;
use std::fs;
use std::os::fd::AsRawFd as _;
if let Some(handle) = &self.driver_handle {
let drm_path = self.common.get_drm_render()?;
let drm_file = fs::OpenOptions::new()
.read(true)
.write(true)
.open(drm_path)
.context("Could not open DRM file")?;
for (key, display_info) in &mut info.displays {
match driver::connector_id_to_display_id(
display_info.connector_id,
drm_file.as_raw_fd(),
) {
Ok(display_id) => {
if let DisplayConnector::DisplayPort {
lanes, bandwidth, ..
} = &mut display_info.connector_type
{
match handle.get_dp_link_config(display_id) {
Ok(params) => {
*lanes = params.laneCount.try_into()?;
*bandwidth =
crate::server::display::dp_rate_to_bandwidth(params.linkBW);
}
Err(err) => {
warn!("could not fetch DP info for display {key}: {err:#}");
}
}
}
}
Err(err) => {
warn!(
"could not resolve display '{key}' into the driver display id: {err:#}"
);
}
}
}
}
Ok(())
}
}
@@ -1,20 +1,20 @@
use std::{
ffi::c_void,
fs::File,
mem,
os::fd::{AsRawFd, RawFd},
os::fd::{AsRawFd, OwnedFd, RawFd},
ptr,
};
use crate::bindings::nvidia::{
NV_ESC_REGISTER_FD, NV_ESC_RM_ALLOC, NV_ESC_RM_CONTROL, NV_IOCTL_MAGIC, NV01_DEVICE_0,
NV20_SUBDEVICE_0, NV0080_ALLOC_PARAMETERS, NV2080_ALLOC_PARAMETERS,
NV2080_CTRL_CMD_FB_GET_INFO, NV2080_CTRL_CMD_GR_GET_GLOBAL_SM_ORDER,
NV2080_CTRL_CMD_GR_GET_ROP_INFO, NV2080_CTRL_FB_GET_INFO_PARAMS, NV2080_CTRL_FB_INFO,
NV2080_CTRL_FB_INFO_INDEX_BUS_WIDTH, NV2080_CTRL_FB_INFO_INDEX_L2CACHE_SIZE,
NV2080_CTRL_FB_INFO_INDEX_MEMORYINFO_VENDOR_ID, NV2080_CTRL_FB_INFO_INDEX_RAM_TYPE,
NV2080_CTRL_FB_INFO_MEMORYINFO_VENDOR_ID_ELPIDA, NV2080_CTRL_FB_INFO_MEMORYINFO_VENDOR_ID_ESMT,
NV2080_CTRL_FB_INFO_MEMORYINFO_VENDOR_ID_ETRON, NV2080_CTRL_FB_INFO_MEMORYINFO_VENDOR_ID_HYNIX,
DRM_COMMAND_BASE, DRM_IOCTL_BASE, DRM_NVIDIA_GET_DPY_ID_FOR_CONNECTOR_ID, NV_ESC_REGISTER_FD,
NV_ESC_RM_ALLOC, NV_ESC_RM_CONTROL, NV_IOCTL_MAGIC, NV01_DEVICE_0, NV20_SUBDEVICE_0,
NV0080_ALLOC_PARAMETERS, NV2080_ALLOC_PARAMETERS, NV2080_CTRL_CMD_FB_GET_INFO,
NV2080_CTRL_CMD_GR_GET_GLOBAL_SM_ORDER, NV2080_CTRL_CMD_GR_GET_ROP_INFO,
NV2080_CTRL_FB_GET_INFO_PARAMS, NV2080_CTRL_FB_INFO, NV2080_CTRL_FB_INFO_INDEX_BUS_WIDTH,
NV2080_CTRL_FB_INFO_INDEX_L2CACHE_SIZE, NV2080_CTRL_FB_INFO_INDEX_MEMORYINFO_VENDOR_ID,
NV2080_CTRL_FB_INFO_INDEX_RAM_TYPE, NV2080_CTRL_FB_INFO_MEMORYINFO_VENDOR_ID_ELPIDA,
NV2080_CTRL_FB_INFO_MEMORYINFO_VENDOR_ID_ESMT, NV2080_CTRL_FB_INFO_MEMORYINFO_VENDOR_ID_ETRON,
NV2080_CTRL_FB_INFO_MEMORYINFO_VENDOR_ID_HYNIX,
NV2080_CTRL_FB_INFO_MEMORYINFO_VENDOR_ID_MICRON,
NV2080_CTRL_FB_INFO_MEMORYINFO_VENDOR_ID_MOSEL, NV2080_CTRL_FB_INFO_MEMORYINFO_VENDOR_ID_NANYA,
NV2080_CTRL_FB_INFO_MEMORYINFO_VENDOR_ID_QIMONDA,
@@ -32,30 +32,37 @@ use crate::bindings::nvidia::{
NV2080_CTRL_FB_INFO_RAM_TYPE_SDDR4, NV2080_CTRL_FB_INFO_RAM_TYPE_SDRAM,
NV2080_CTRL_FB_INFO_RAM_TYPE_UNKNOWN, NV2080_CTRL_GR_GET_GLOBAL_SM_ORDER_PARAMS,
NV2080_CTRL_GR_GET_ROP_INFO_PARAMS, NVOS21_PARAMETERS, NVOS54_PARAMETERS, NVOS64_PARAMETERS,
NvHandle,
NvHandle, NvU32, drm_nvidia_get_dpy_id_for_connector_id_params,
};
#[cfg(feature = "display-info")]
use crate::bindings::nvidia::{
NV04_DISPLAY_COMMON, NV0073_CTRL_CMD_DP_GET_LINK_CONFIG, NV0073_CTRL_DP_GET_LINK_CONFIG_PARAMS,
};
use anyhow::{Context, bail};
use lact_schema::RopInfo;
use nix::ioctl_readwrite;
pub struct DriverHandle {
nvidiactl_fd: File,
nvidiactl_fd: OwnedFd,
#[allow(dead_code)]
device_fd: File,
device_fd: OwnedFd,
client_handle: NvHandle,
#[allow(dead_code)]
device_handle: NvHandle,
subdevice_handle: NvHandle,
#[cfg(feature = "display-info")]
display_handle: Option<NvHandle>,
}
impl DriverHandle {
pub fn open(minor_number: u32) -> anyhow::Result<Self> {
let nvidiactl_fd = File::options()
let nvidiactl_fd: OwnedFd = File::options()
.read(true)
.write(true)
.open("/dev/nvidiactl")
.context("Could not open nvidiactl")?;
.context("Could not open nvidiactl")?
.into();
let client_handle: NvHandle = unsafe {
let mut client_request: NVOS21_PARAMETERS = mem::zeroed();
@@ -63,66 +70,55 @@ impl DriverHandle {
client_request.hObjectNew
};
let device_fd = File::options()
let device_fd: OwnedFd = File::options()
.read(true)
.write(true)
.open(format!("/dev/nvidia{minor_number}"))
.context("Could not open nvidia device")?;
.context("Could not open nvidia device")?
.into();
let device_handle: NvHandle = unsafe {
register_fd(device_fd.as_raw_fd(), &mut nvidiactl_fd.as_raw_fd())?;
let mut alloc_params: NV0080_ALLOC_PARAMETERS = mem::zeroed();
alloc_params.deviceId = minor_number;
let mut request = NVOS64_PARAMETERS {
hRoot: client_handle,
hObjectParent: client_handle,
hObjectNew: 0,
hClass: NV01_DEVICE_0,
pAllocParms: ptr::from_mut(&mut alloc_params).cast::<c_void>(),
pRightsRequested: ptr::null_mut(),
paramsSize: 0,
flags: 0,
status: 0,
};
rm_alloc_nvos64(nvidiactl_fd.as_raw_fd(), &raw mut request)?;
if request.status != 0 {
bail!(
"Got error status {} on Nvidia device handle creation",
request.status
);
}
request.hObjectNew
alloc_object(
client_handle,
client_handle,
NV01_DEVICE_0,
Some(&mut alloc_params),
nvidiactl_fd.as_raw_fd(),
)?
};
let subdevice_handle: NvHandle = unsafe {
let mut alloc_params: NV2080_ALLOC_PARAMETERS = mem::zeroed();
let mut request = NVOS64_PARAMETERS {
hRoot: client_handle,
hObjectParent: device_handle,
hObjectNew: 0,
hClass: NV20_SUBDEVICE_0,
pAllocParms: ptr::from_mut(&mut alloc_params).cast(),
pRightsRequested: ptr::null_mut(),
paramsSize: 0,
flags: 0,
status: 0,
};
alloc_object(
client_handle,
device_handle,
NV20_SUBDEVICE_0,
Some(&mut alloc_params),
nvidiactl_fd.as_raw_fd(),
)?
};
rm_alloc_nvos64(nvidiactl_fd.as_raw_fd(), &raw mut request)?;
#[cfg(feature = "display-info")]
let display_handle = unsafe {
use tracing::warn;
if request.status != 0 {
bail!(
"Got error status {} on Nvidia subdevice handle creation",
request.status
);
}
request.hObjectNew
alloc_object::<()>(
client_handle,
device_handle,
NV04_DISPLAY_COMMON,
None,
nvidiactl_fd.as_raw_fd(),
)
.inspect_err(|err| {
warn!("could not allocate display handle: {err:#}");
})
.ok()
};
Ok(Self {
@@ -131,6 +127,8 @@ impl DriverHandle {
client_handle,
device_handle,
subdevice_handle,
#[cfg(feature = "display-info")]
display_handle,
})
}
@@ -215,6 +213,35 @@ impl DriverHandle {
self.get_fb_info(NV2080_CTRL_FB_INFO_INDEX_L2CACHE_SIZE)
}
#[cfg(feature = "display-info")]
pub fn get_dp_link_config(
&self,
display_id: u32,
) -> anyhow::Result<NV0073_CTRL_DP_GET_LINK_CONFIG_PARAMS> {
let display_obj = self
.display_handle
.context("Display object not available")?;
let mut params = NV0073_CTRL_DP_GET_LINK_CONFIG_PARAMS {
subDeviceInstance: 0,
displayId: display_id,
laneCount: 0,
linkBW: 0,
dp2LinkBW: 0,
bFECEnabled: 0,
};
unsafe {
self.query_rm_control_on_object(
NV0073_CTRL_CMD_DP_GET_LINK_CONFIG,
display_obj,
&mut params,
)?;
}
Ok(params)
}
fn get_fb_info(&self, stat_index: u32) -> anyhow::Result<u32> {
let mut info_list = vec![NV2080_CTRL_FB_INFO {
index: stat_index,
@@ -225,15 +252,26 @@ impl DriverHandle {
fbInfoList: info_list.as_mut_ptr().cast(),
};
self.query_rm_control(NV2080_CTRL_CMD_FB_GET_INFO, &mut params)?;
unsafe {
self.query_rm_control(NV2080_CTRL_CMD_FB_GET_INFO, &mut params)?;
}
Ok(info_list[0].data)
}
fn query_rm_control<T: Copy>(&self, cmd: u32, params: &mut T) -> anyhow::Result<()> {
unsafe fn query_rm_control<T: Copy>(&self, cmd: u32, params: &mut T) -> anyhow::Result<()> {
unsafe { self.query_rm_control_on_object(cmd, self.subdevice_handle, params) }
}
unsafe fn query_rm_control_on_object<T: Copy>(
&self,
cmd: u32,
object: u32,
params: &mut T,
) -> anyhow::Result<()> {
let mut request = NVOS54_PARAMETERS {
hClient: self.client_handle,
hObject: self.subdevice_handle,
hObject: object,
cmd,
flags: 0,
params: ptr::from_mut(params).cast(),
@@ -252,6 +290,50 @@ impl DriverHandle {
}
}
#[cfg(feature = "display-info")]
pub fn connector_id_to_display_id(connector_id: u32, drm_device: RawFd) -> anyhow::Result<u32> {
let mut params = drm_nvidia_get_dpy_id_for_connector_id_params {
connectorId: connector_id,
dpyId: 0,
};
unsafe {
get_dpy_id_for_connector_id(drm_device, &raw mut params)?;
}
Ok(params.dpyId)
}
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn alloc_object<T>(
root: NvU32,
parent: NvU32,
class: NvU32,
alloc_params: Option<&mut T>,
nvidiactl_fd: RawFd,
) -> anyhow::Result<NvU32> {
let mut request = NVOS64_PARAMETERS {
hRoot: root,
hObjectParent: parent,
hObjectNew: 0,
hClass: class,
pAllocParms: alloc_params.map_or(ptr::null_mut(), |params| ptr::from_mut(params).cast()),
pRightsRequested: ptr::null_mut(),
paramsSize: 0,
flags: 0,
status: 0,
};
rm_alloc_nvos64(nvidiactl_fd, &raw mut request)?;
if request.status != 0 {
bail!(
"Got error status {} on Nvidia object class {class} allocation",
request.status
);
}
Ok(request.hObjectNew)
}
ioctl_readwrite!(
rm_alloc_nvos21,
NV_IOCTL_MAGIC,
@@ -274,3 +356,10 @@ ioctl_readwrite!(
NV_ESC_RM_CONTROL,
NVOS54_PARAMETERS
);
ioctl_readwrite!(
get_dpy_id_for_connector_id,
DRM_IOCTL_BASE,
DRM_COMMAND_BASE + DRM_NVIDIA_GET_DPY_ID_FOR_CONNECTOR_ID,
drm_nvidia_get_dpy_id_for_connector_id_params
);
+23 -3
View File
@@ -3,6 +3,8 @@ use super::{
profiles::ProfileWatcherCommand,
system::{self},
};
#[cfg(feature = "display-info")]
use crate::server::display;
use crate::{
bindings::intel::IntelDrm,
config::Config,
@@ -14,9 +16,9 @@ use amdgpu_sysfs::gpu_handle::{
};
use anyhow::{Context, anyhow, bail};
use lact_schema::{
ClocksInfo, DeviceApiInfo, DeviceInfo, DeviceListEntry, DeviceStats, FanControlMode,
FanOptions, PmfwOptions, PowerStates, ProcessList, ProfileRule, ProfileWatcherState,
ProfilesInfo,
ClocksInfo, DeviceApiInfo, DeviceInfo, DeviceListEntry, DeviceStats, DisplaysInfo,
FanControlMode, FanOptions, PmfwOptions, PowerStates, ProcessList, ProfileRule,
ProfileWatcherState, ProfilesInfo,
config::{
FanControlSettings, FanCurve, GpuConfig, Profile, ProfileHooks, default_fan_static_speed,
},
@@ -463,6 +465,24 @@ impl<'a> Handler {
self.controller_by_id(id).await?.get_clocks_info(gpu_config)
}
#[cfg(feature = "display-info")]
pub async fn get_displays_info(&'a self, id: &str) -> anyhow::Result<DisplaysInfo> {
let controller = self.controller_by_id(id).await?;
let common = controller.controller_info();
let mut info = display::get_base_displays_info(&common.sysfs_path)?;
if let Err(err) = controller.populate_displays_info(&mut info) {
warn!("failed to populate displays info: {err:#}");
}
Ok(info)
}
#[cfg(not(feature = "display-info"))]
pub async fn get_displays_info(&'a self, _id: &str) -> anyhow::Result<DisplaysInfo> {
Err(anyhow!("Daemon is compiled without display info support"))
}
pub async fn set_fan_control(&'a self, opts: FanOptions<'_>) -> anyhow::Result<u64> {
let settings = {
let mut config_guard = self.config.write().await;
+18 -9
View File
@@ -1,7 +1,8 @@
info-page = Hardware Info
oc-page = Overclocking
thermals-page = Thermals
thermals-page = Thermals
software-page = Software Info
displays-page = Display Info
hardware-info = Hardware Information
@@ -79,10 +80,10 @@ amd-oc-detected-system-config = Detected system configuration: <b>{$config ->
[unsupported] Unsupported
*[other] {$config}
}</b>
amd-oc-description =
amd-oc-description =
{$config ->
[rpm-ostree] This option will toggle AMD overdrive support by setting boot flags through <b>rpm-ostree</b>.
[unsupported]
[unsupported]
The current system is not recognized as supported for automatic overdrive configuration.
You may attempt to enable overclocking from LACT, but a manual initramfs regeneration may be required for it to take effect.
If that fails, a fallback option is to add <b>amdgpu.ppfeaturemask=0xffffffff</b> as a boot parameter in your bootloader.
@@ -145,7 +146,7 @@ manual-level-needed = Performance level has to be set to "manual" to use power s
overclock-section = Clockspeed and Voltage
nvidia-oc-info = Overclocking Information
nvidia-oc-description =
nvidia-oc-description =
Overclocking functionality on Nvidia includes setting offsets for GPU/VRAM clockspeeds and limiting the potential range of clockspeeds using the "locked clocks" feature.
On many cards, the VRAM clockpeed offset will only affect the actual memory clockspeed by half of the offset value.
@@ -163,7 +164,7 @@ pstate-list-description = <b>The following values are clock offsets for each P-S
no-clocks-data = No clocks data available
reset-oc-tooltip = Warning: this resets all clock settings to defaults!
vf-curve-editor = VF Curve Editor
nvidia-vf-curve-warning = The voltage-frequency curve editor relies on undocumented driver functionality.
nvidia-vf-curve-warning = The voltage-frequency curve editor relies on undocumented driver functionality.
There are no guarantees regarding its behaviour, safety or availability.
<span weight = "heavy" underline = "single">Use at your own risk</span>.
vf-curve-enable-editing = Enable Editing
@@ -177,11 +178,11 @@ vf-curve-flatten-right = Flatten curve to the right
gpu-clock-offset = GPU Clock Offset (MHz)
max-gpu-clock = Maximum GPU Clock (MHz)
max-vram-clock = Maximum VRAM Clock (MHz)
max-gpu-voltage = Maximum GPU Voltage (mV)
max-vram-clock = Maximum VRAM Clock (MHz)
max-gpu-voltage = Maximum GPU Voltage (mV)
min-gpu-clock = Minimum GPU Clock (MHz)
min-vram-clock = Minimum VRAM Clock (MHz)
min-gpu-voltage = Minimum GPU Voltage (mV)
min-vram-clock = Minimum VRAM Clock (MHz)
min-gpu-voltage = Minimum GPU Voltage (mV)
gpu-voltage-offset = GPU voltage offset (mV)
gpu-pstate-clock-offset = GPU P-State {$pstate} Clock Offset (MHz)
vram-pstate-clock-offset = VRAM P-State {$pstate} Clock Offset (MHz)
@@ -232,6 +233,14 @@ version-mismatch-description =
plot-show-detailed-info = Show detailed info
display-title = Display {$identifier}
display-manufacturer = Manufacturer
display-product-code = Product Code
display-model = Model
display-physical-size = Physical Size
display-connection = Connection
display-manufacture-date = Manufacture Date
settings-profile = Settings Profile
auto-switch-profiles = Switch automatically
add-profile = Add new profile
+16
View File
@@ -21,6 +21,7 @@ use crate::{
InfoDialog, InfoDialogConfirmation, InfoDialogData, InfoDialogId, InfoDialogMsg,
},
overdrive_dialog::{OverdriveDialog, OverdriveDialogMsg},
pages::displays_page::DisplaysPage,
preferences_dialog::{PreferencesDialog, PreferencesDialogMsg},
process_monitor::{ProcessMonitorWindow, ProcessMonitorWindowMsg},
profiles::{
@@ -112,6 +113,7 @@ pub struct AppModel {
oc_page: relm4::Controller<OcPage>,
thermals_page: relm4::Controller<ThermalsPage>,
software_page: relm4::Controller<SoftwarePage>,
displays_page: relm4::Controller<DisplaysPage>,
crash_page: relm4::Controller<CrashPage>,
gpu_selector: relm4::Controller<GpuSelector>,
@@ -293,6 +295,7 @@ impl AsyncComponent for AppModel {
add_titled[Some("oc_page"), &fl!(I18N, "oc-page")] = model.oc_page.widget(),
add_titled[Some("thermals_page"), &fl!(I18N, "thermals-page")] = model.thermals_page.widget(),
add_titled[Some("software_page"), &fl!(I18N, "software-page")] = model.software_page.widget(),
add_titled[Some("displays_page"), &fl!(I18N, "displays-page")] = model.displays_page.widget(),
add_named[Some("crash_page")] = model.crash_page.widget(),
set_visible_child_name: &CONFIG.read().selected_tab,
@@ -433,6 +436,8 @@ impl AsyncComponent for AppModel {
let software_page = SoftwarePage::detach((system_info.clone(), daemon_client.embedded));
let displays_page = DisplaysPage::detach_default();
let crash_page = CrashPage::launch_default().forward(sender.input_sender(), |msg| msg);
let overdrive_dialog =
@@ -496,6 +501,7 @@ impl AsyncComponent for AppModel {
thermals_page,
software_page,
crash_page,
displays_page,
gpu_selector,
profile_selector,
ui_sensitive: BoolBinding::new(false),
@@ -1073,6 +1079,16 @@ impl AppModel {
self.graphs_window
.emit(GraphsWindowMsg::VramClockRatio(vram_clock_ratio));
let displays_info = self
.daemon_client
.get_displays_info(&gpu_id)
.await
.inspect_err(|err| {
warn!("could not fetch displays info: {err:#}");
})
.unwrap_or_default();
self.displays_page.emit(displays_info);
let stats = self.update_gpu_data(gpu_id.clone(), sender).await?;
self.graphs_window.emit(GraphsWindowMsg::Stats {
@@ -29,6 +29,12 @@ impl PageSection {
}
}
impl Default for PageSection {
fn default() -> Self {
Self::new("")
}
}
unsafe impl<T: ObjectSubclass + BoxImpl> IsSubclassable<T> for PageSection {}
mod imp {
+174
View File
@@ -0,0 +1,174 @@
use crate::{
I18N,
app::{
components::{info_row::InfoRow, page_section::PageSection},
utils::ext::FlowBoxExt as _,
},
};
use gtk::prelude::{BoxExt as _, OrientableExt as _, WidgetExt as _};
use i18n_embed_fl::fl;
use lact_schema::{DisplayConnector, DisplayInfo, DisplaysInfo};
use relm4::{
ComponentParts, ComponentSender, FactorySender, RelmWidgetExt as _,
prelude::{DynamicIndex, FactoryVecDeque},
};
use std::fmt::Write as _;
pub struct DisplaysPage {
displays: FactoryVecDeque<DisplayComponent>,
}
#[relm4::component(pub)]
impl relm4::SimpleComponent for DisplaysPage {
type Init = ();
type Input = DisplaysInfo;
type Output = ();
view! {
gtk::Box {
#[local_ref]
displays_list -> gtk::Box {
set_orientation: gtk::Orientation::Vertical,
set_spacing: 15,
set_margin_all: 15,
}
}
}
fn init(
_init: Self::Init,
root: Self::Root,
_sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let model = Self {
displays: FactoryVecDeque::builder().launch_default().detach(),
};
let displays_list = model.displays.widget();
let widgets = view_output!();
ComponentParts { model, widgets }
}
fn update(&mut self, displays_info: Self::Input, _sender: ComponentSender<Self>) {
let mut guard = self.displays.guard();
guard.clear();
for entry in displays_info.displays {
guard.push_back(entry);
}
}
}
struct DisplayComponent {
display_id: String,
info: DisplayInfo,
}
#[relm4::factory]
impl relm4::factory::FactoryComponent for DisplayComponent {
type Init = (String, DisplayInfo);
type Input = ();
type Output = ();
type ParentWidget = gtk::Box;
type CommandOutput = ();
view! {
PageSection {
set_name: fl!(I18N, "display-title", identifier = self.display_id.clone()),
append_child = &gtk::FlowBox {
set_orientation: gtk::Orientation::Horizontal,
set_column_spacing: 10,
set_homogeneous: true,
set_min_children_per_line: 2,
set_max_children_per_line: 4,
set_selection_mode: gtk::SelectionMode::None,
append_child = &InfoRow {
set_name: fl!(I18N, "display-manufacturer"),
set_value: self.info.manufacturer.as_deref().unwrap_or("N/A"),
set_selectable: true,
},
append_child = &InfoRow {
set_name: fl!(I18N, "display-product-code"),
set_value: self.info.product_code.to_string(),
set_selectable: true,
},
append_child = &InfoRow {
set_name: fl!(I18N, "display-model"),
set_value: self.info.model.as_deref().unwrap_or("N/A"),
set_selectable: true,
},
append_child = &InfoRow {
set_name: fl!(I18N, "display-physical-size"),
set_value: self.info.size.map(|(width, height)| {
format!("{width}cm x {height}cm")
}).unwrap_or_default(),
set_selectable: true,
set_visible: self.info.size.is_some(),
},
append_child = &InfoRow {
set_name: fl!(I18N, "display-connection"),
set_value: self.format_connector(),
set_selectable: true,
},
append_child = &InfoRow {
set_name: fl!(I18N, "display-manufacture-date"),
set_value: self.info.manufacture_date.map(|date| {
if date.week == 0 {
date.year.to_string()
} else {
format!("{}, Week {}", date.year, date.week)
}
}).unwrap_or_default(),
set_selectable: true,
set_visible: self.info.manufacture_date.is_some(),
},
},
}
}
fn init_model(
(display_id, info): Self::Init,
_index: &DynamicIndex,
_sender: FactorySender<Self>,
) -> Self {
Self { display_id, info }
}
}
impl DisplayComponent {
fn format_connector(&self) -> String {
match self.info.connector_type {
DisplayConnector::DisplayPort {
lanes,
bandwidth,
embedded,
} => {
let mut text = "DisplayPort".to_owned();
if embedded {
text.push_str(" (Internal)")
}
let lane_rate = bandwidth as f64 / 1000.0;
write!(
text,
" @ {} Gbps ({lane_rate} Gbps x {lanes} lanes)",
lane_rate * lanes as f64
)
.unwrap();
text
}
DisplayConnector::Hdmi => "HDMI".to_owned(),
DisplayConnector::Dvi => "DVI".to_owned(),
DisplayConnector::Vga => "VGA".to_owned(),
DisplayConnector::Other => fl!(I18N, "unknown-throttling"),
}
}
}
+1
View File
@@ -1,4 +1,5 @@
pub mod crash_page;
pub mod displays_page;
pub mod info_page;
pub mod oc_page;
pub mod software_page;
+37
View File
@@ -864,3 +864,40 @@ pub enum ProcessType {
Graphics,
Compute,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct DisplaysInfo {
pub displays: BTreeMap<String, DisplayInfo>,
}
#[skip_serializing_none]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct DisplayInfo {
pub model: Option<String>,
pub manufacturer: Option<String>,
pub product_code: u16,
pub manufacture_date: Option<DisplayManufactureDate>,
pub size: Option<(u32, u32)>,
pub connector_type: DisplayConnector,
pub connector_id: u32,
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
pub struct DisplayManufactureDate {
pub year: u16,
pub week: u8,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum DisplayConnector {
DisplayPort {
lanes: u16,
/// Per-lane bandwidth in Mbps
bandwidth: u32,
embedded: bool,
},
Hdmi,
Dvi,
Vga,
Other,
}
+3
View File
@@ -24,6 +24,9 @@ pub enum Request<'a> {
DeviceStats {
id: &'a str,
},
DisplaysInfo {
id: &'a str,
},
DeviceClocksInfo {
id: &'a str,
},
+2 -1
View File
@@ -4,8 +4,9 @@ version = "0.9.1"
edition.workspace = true
[features]
default = ["lact-gui", "nvidia"]
default = ["lact-gui", "nvidia", "display-info"]
nvidia = ["lact-daemon/nvidia"]
display-info = ["lact-daemon/display-info"]
[dependencies]
lact-daemon = { path = "../lact-daemon", default-features = false }
+2 -2
View File
@@ -2,7 +2,7 @@ FROM rust:1.93-trixie AS builder
WORKDIR /app
RUN apt update -y && apt install -y build-essential clang libdrm-dev pkg-config ocl-icd-opencl-dev
RUN apt update -y && apt install -y build-essential clang libdrm-dev pkg-config ocl-icd-opencl-dev libdisplay-info-dev
COPY rust-toolchain.toml /app
RUN cargo --version
@@ -15,7 +15,7 @@ RUN --mount=type=cache,target=/usr/local/cargo/registry \
FROM debian:trixie-slim
RUN apt update -y && apt install -y libdrm-amdgpu1 libdrm-radeon1 libdrm-intel1 libdrm2 hwdata vulkan-tools && rm -rf /var/cache
RUN apt update -y && apt install -y libdrm-amdgpu1 libdrm-radeon1 libdrm-intel1 libdrm2 hwdata vulkan-tools libdisplay-info2 && rm -rf /var/cache
COPY --from=builder /usr/local/bin/lact /usr/local/bin/lact
+8 -8
View File
@@ -12,16 +12,16 @@ metadata:
conflicts: [ lact-headless ]
depends:
all: [ hwdata, vulkan-tools, clinfo ]
debian-13+ubuntu-2404+ubuntu-2604: [ libgtk-4-1, libdrm2, libdrm-amdgpu1, libadwaita-1-0 ]
fedora-43+fedora-44: [ gtk4, libdrm, libadwaita ]
arch: [ gtk4, ocl-icd, libadwaita ]
opensuse-tumbleweed: [ gtk4, libadwaita-1-0 ]
debian-13+ubuntu-2404+ubuntu-2604: [ libgtk-4-1, libdrm2, libdrm-amdgpu1, libadwaita-1-0, libdisplay-info ]
fedora-43+fedora-44: [ gtk4, libdrm, libadwaita, libdisplay-info ]
arch: [ gtk4, ocl-icd, libadwaita, libdisplay-info ]
opensuse-tumbleweed: [ gtk4, libadwaita-1-0, libdisplay-info ]
build_depends:
all: [ curl, make, clang, git, vulkan-tools, clinfo ]
debian-13+ubuntu-2404+ubuntu-2604: [ libgtk-4-dev, pkg-config, build-essential, libdrm-dev, dbus, libadwaita-1-dev ]
fedora-43+fedora-44: [ gtk4-devel, gcc, libdrm-devel, dbus, libadwaita-devel ]
arch: [ gtk4, dbus, ocl-icd, libadwaita ]
opensuse-tumbleweed: [ gtk4-devel, libdrm-devel, libadwaita-devel ]
debian-13+ubuntu-2404+ubuntu-2604: [ libgtk-4-dev, pkg-config, build-essential, libdrm-dev, dbus, libadwaita-1-dev, libdisplay-info-dev ]
fedora-43+fedora-44: [ gtk4-devel, gcc, libdrm-devel, dbus, libadwaita-devel, libdisplay-info-devel ]
arch: [ gtk4, dbus, ocl-icd, libadwaita, libdisplay-info ]
opensuse-tumbleweed: [ gtk4-devel, libdrm-devel, libadwaita-devel, libdisplay-info-devel ]
all_images: true
env:
RUSTUP_URL: https://sh.rustup.rs