sync with OpenBSD -current

This commit is contained in:
purplerain 2024-01-31 02:14:33 +00:00
parent abc24a81d1
commit 921461fcd8
Signed by: purplerain
GPG Key ID: F42C07F07E2E35B7
53 changed files with 2169 additions and 443 deletions

View File

@ -1,5 +1,5 @@
# $OpenBSD: 3RDPARTY,v 1.421 2024/01/16 13:14:26 matthieu Exp $
# $OpenBSD: 3RDPARTY,v 1.422 2024/01/30 07:50:26 jsg Exp $
#
Package: Freetype
Version: 2.13.0
@ -15,12 +15,12 @@ Archive Site: https://invisible-island.net/xterm/xterm.html
Package: Mesa
Version 23.1.9
Current Vers: 23.3.2
Current Vers: 23.3.4
Maintainer: Brian Paul
Archive Site: https://archive.mesa3d.org/
Package: libdrm
Version: 2.4.115
Version: 2.4.120
Current Vers: 2.4.120
Maintainer: Freedesktop.org
Archive Site: https://dri.freedesktop.org/libdrm/

View File

@ -268,9 +268,9 @@
./usr/X11R6/lib/libOSMesa.so.13.0
./usr/X11R6/lib/libOSMesa_p.a
./usr/X11R6/lib/libdrm.a
./usr/X11R6/lib/libdrm.so.7.12
./usr/X11R6/lib/libdrm.so.7.13
./usr/X11R6/lib/libdrm_amdgpu.a
./usr/X11R6/lib/libdrm_amdgpu.so.1.12
./usr/X11R6/lib/libdrm_amdgpu.so.1.13
./usr/X11R6/lib/libdrm_amdgpu_p.a
./usr/X11R6/lib/libdrm_intel.a
./usr/X11R6/lib/libdrm_intel.so.5.4

View File

@ -259,9 +259,9 @@
./usr/X11R6/lib/libOSMesa.so.13.0
./usr/X11R6/lib/libOSMesa_p.a
./usr/X11R6/lib/libdrm.a
./usr/X11R6/lib/libdrm.so.7.12
./usr/X11R6/lib/libdrm.so.7.13
./usr/X11R6/lib/libdrm_amdgpu.a
./usr/X11R6/lib/libdrm_amdgpu.so.1.12
./usr/X11R6/lib/libdrm_amdgpu.so.1.13
./usr/X11R6/lib/libdrm_amdgpu_p.a
./usr/X11R6/lib/libdrm_p.a
./usr/X11R6/lib/libdrm_radeon.a

View File

@ -259,9 +259,9 @@
./usr/X11R6/lib/libOSMesa.so.13.0
./usr/X11R6/lib/libOSMesa_p.a
./usr/X11R6/lib/libdrm.a
./usr/X11R6/lib/libdrm.so.7.12
./usr/X11R6/lib/libdrm.so.7.13
./usr/X11R6/lib/libdrm_amdgpu.a
./usr/X11R6/lib/libdrm_amdgpu.so.1.12
./usr/X11R6/lib/libdrm_amdgpu.so.1.13
./usr/X11R6/lib/libdrm_amdgpu_p.a
./usr/X11R6/lib/libdrm_p.a
./usr/X11R6/lib/libdrm_radeon.a

View File

@ -268,9 +268,9 @@
./usr/X11R6/lib/libOSMesa.so.13.0
./usr/X11R6/lib/libOSMesa_p.a
./usr/X11R6/lib/libdrm.a
./usr/X11R6/lib/libdrm.so.7.12
./usr/X11R6/lib/libdrm.so.7.13
./usr/X11R6/lib/libdrm_amdgpu.a
./usr/X11R6/lib/libdrm_amdgpu.so.1.12
./usr/X11R6/lib/libdrm_amdgpu.so.1.13
./usr/X11R6/lib/libdrm_amdgpu_p.a
./usr/X11R6/lib/libdrm_intel.a
./usr/X11R6/lib/libdrm_intel.so.5.4

View File

@ -63,6 +63,7 @@ amdgpu_query_crtc_from_id
amdgpu_query_firmware_version
amdgpu_query_gds_info
amdgpu_query_gpu_info
amdgpu_query_gpuvm_fault_info
amdgpu_query_heap_info
amdgpu_query_hw_ip_count
amdgpu_query_hw_ip_info
@ -72,6 +73,7 @@ amdgpu_query_video_caps_info
amdgpu_read_mm_registers
amdgpu_va_range_alloc
amdgpu_va_range_free
amdgpu_va_get_start_addr
amdgpu_va_range_query
amdgpu_vm_reserve_vmid
amdgpu_vm_unreserve_vmid

View File

@ -1282,6 +1282,22 @@ int amdgpu_query_sensor_info(amdgpu_device_handle dev, unsigned sensor_type,
int amdgpu_query_video_caps_info(amdgpu_device_handle dev, unsigned cap_type,
unsigned size, void *value);
/**
* Query information about VM faults
*
* The return sizeof(struct drm_amdgpu_info_gpuvm_fault)
*
* \param dev - \c [in] Device handle. See #amdgpu_device_initialize()
* \param size - \c [in] Size of the returned value.
* \param value - \c [out] Pointer to the return value.
*
* \return 0 on success\n
* <0 - Negative POSIX Error code
*
*/
int amdgpu_query_gpuvm_fault_info(amdgpu_device_handle dev, unsigned size,
void *value);
/**
* Read a set of consecutive memory-mapped registers.
* Not all registers are allowed to be read by userspace.
@ -1368,6 +1384,11 @@ int amdgpu_va_range_alloc(amdgpu_device_handle dev,
*/
int amdgpu_va_range_free(amdgpu_va_handle va_range_handle);
/**
* Return the starting address of the allocated virtual address range.
*/
uint64_t amdgpu_va_get_start_addr(amdgpu_va_handle va_handle);
/**
* Query virtual address range
*

View File

@ -551,7 +551,7 @@ drm_public int amdgpu_find_bo_by_cpu_mapping(amdgpu_device_handle dev,
if (!bo || !bo->cpu_ptr || size > bo->alloc_size)
continue;
if (cpu >= bo->cpu_ptr &&
cpu < (void*)((uintptr_t)bo->cpu_ptr + bo->alloc_size))
cpu < (void*)((uintptr_t)bo->cpu_ptr + (size_t)bo->alloc_size))
break;
}

View File

@ -56,10 +56,22 @@ drm_public int amdgpu_cs_ctx_create2(amdgpu_device_handle dev,
union drm_amdgpu_ctx args;
int i, j, k;
int r;
char *override_priority;
if (!dev || !context)
return -EINVAL;
override_priority = getenv("AMD_PRIORITY");
if (override_priority) {
/* The priority is a signed integer. The variable type is
* wrong. If parsing fails, priority is unchanged.
*/
if (sscanf(override_priority, "%i", &priority) == 1) {
printf("amdgpu: context priority changed to %i\n",
priority);
}
}
gpu_context = calloc(1, sizeof(struct amdgpu_context));
if (!gpu_context)
return -ENOMEM;
@ -128,8 +140,8 @@ drm_public int amdgpu_cs_ctx_free(amdgpu_context_handle context)
for (i = 0; i < AMDGPU_HW_IP_NUM; i++) {
for (j = 0; j < AMDGPU_HW_IP_INSTANCE_MAX_COUNT; j++) {
for (k = 0; k < AMDGPU_CS_MAX_RINGS; k++) {
amdgpu_semaphore_handle sem;
LIST_FOR_EACH_ENTRY(sem, &context->sem_list[i][j][k], list) {
amdgpu_semaphore_handle sem, tmp;
LIST_FOR_EACH_ENTRY_SAFE(sem, tmp, &context->sem_list[i][j][k], list) {
list_del(&sem->list);
amdgpu_cs_reset_sem(sem);
amdgpu_cs_unreference_sem(sem);

View File

@ -346,3 +346,17 @@ drm_public int amdgpu_query_video_caps_info(amdgpu_device_handle dev, unsigned c
return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
sizeof(struct drm_amdgpu_info));
}
drm_public int amdgpu_query_gpuvm_fault_info(amdgpu_device_handle dev,
unsigned size, void *value)
{
struct drm_amdgpu_info request;
memset(&request, 0, sizeof(request));
request.return_pointer = (uintptr_t)value;
request.return_size = size;
request.query = AMDGPU_INFO_GPUVM_FAULT;
return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
sizeof(struct drm_amdgpu_info));
}

View File

@ -57,7 +57,6 @@ struct amdgpu_bo_va_mgr {
};
struct amdgpu_va {
amdgpu_device_handle dev;
uint64_t address;
uint64_t size;
enum amdgpu_gpu_va_range range;

View File

@ -274,7 +274,6 @@ drm_public int amdgpu_va_range_alloc(amdgpu_device_handle dev,
amdgpu_vamgr_free_va(vamgr, *va_base_allocated, size);
return -ENOMEM;
}
va->dev = dev;
va->address = *va_base_allocated;
va->size = size;
va->range = va_range_type;
@ -296,3 +295,8 @@ drm_public int amdgpu_va_range_free(amdgpu_va_handle va_range_handle)
free(va_range_handle);
return 0;
}
drm_public uint64_t amdgpu_va_get_start_addr(amdgpu_va_handle va_handle)
{
return va_handle->address;
}

View File

@ -36,7 +36,7 @@ libdrm_amdgpu = library(
],
include_directories : [inc_root, inc_drm],
link_with : libdrm,
dependencies : [dep_pthread_stubs, dep_atomic_ops, dep_rt],
dependencies : [dep_threads, dep_atomic_ops, dep_rt],
version : '1.0.0',
install : true,
)
@ -65,6 +65,6 @@ test(
args : [
'--lib', libdrm_amdgpu,
'--symbols-file', files('amdgpu-symbols.txt'),
'--nm', prog_nm.path(),
'--nm', prog_nm.full_path(),
],
)

View File

@ -70,6 +70,7 @@ drmGetLibVersion
drmGetLock
drmGetMagic
drmGetMap
drmGetNodeTypeFromDevId
drmGetNodeTypeFromFd
drmGetPrimaryDeviceNameFromFd
drmGetRenderDeviceNameFromFd
@ -103,6 +104,7 @@ drmModeAtomicGetCursor
drmModeAtomicMerge
drmModeAtomicSetCursor
drmModeAttachMode
drmModeCloseFB
drmModeConnectorGetPossibleCrtcs
drmModeConnectorSetProperty
drmModeCreateDumbBuffer
@ -187,6 +189,7 @@ drmSLNext
drmSwitchToContext
drmSyncobjCreate
drmSyncobjDestroy
drmSyncobjEventfd
drmSyncobjExportSyncFile
drmSyncobjFDToHandle
drmSyncobjHandleToFD

View File

@ -396,8 +396,20 @@
743F, CC, AMD Radeon 6550S
743F, CF, AMD Radeon RX 6300M
743F, D7, AMD Radeon RX 6400
7448, 00, AMD Radeon Pro W7900
744C, C8, AMD Radeon RX 7900 XTX
744C, CC, AMD Radeon RX 7900 XT
744C, CE, AMD Radeon RX 7900 GRE
745E, CC, AMD Radeon Pro W7800
747E, C8, AMD Radeon RX 7800 XT
747E, FF, AMD Radeon RX 7700 XT
7480, 00, AMD Radeon Pro W7600
7480, C1, AMD Radeon RX 7700S
7480, C3, AMD Radeon RX 7600S
7480, C7, AMD Radeon RX 7600M XT
7480, CF, AMD Radeon RX 7600
7483, CF, AMD Radeon RX 7600M
7489, 00, AMD Radeon Pro W7500
9830, 00, AMD Radeon HD 8400 / R3 Series
9831, 00, AMD Radeon HD 8400E
9832, 00, AMD Radeon HD 8330

View File

@ -32,7 +32,7 @@ libdrm_etnaviv = library(
link_with : libdrm,
c_args : libdrm_c_args,
gnu_symbol_visibility : 'hidden',
dependencies : [dep_pthread_stubs, dep_rt, dep_atomic_ops],
dependencies : [dep_threads, dep_rt, dep_atomic_ops],
version : '1.0.0',
install : true,
)

View File

@ -25,7 +25,7 @@ libdrm_exynos = library(
gnu_symbol_visibility : 'hidden',
include_directories : [inc_root, inc_drm],
link_with : libdrm,
dependencies : [dep_pthread_stubs],
dependencies : [dep_threads],
version : '1.0.0',
install : true,
)

View File

@ -44,7 +44,7 @@ libdrm_freedreno = library(
[files_freedreno, config_file],
c_args : libdrm_c_args,
include_directories : [inc_root, inc_drm],
dependencies : [dep_valgrind, dep_pthread_stubs, dep_rt, dep_atomic_ops],
dependencies : [dep_valgrind, dep_threads, dep_rt, dep_atomic_ops],
link_with : libdrm,
version : '1.0.0',
install : true,

View File

@ -15,6 +15,9 @@ static const struct drmFormatModifierInfo drm_format_modifier_table[] = {
{ DRM_MODIFIER_INTEL(4_TILED_DG2_RC_CCS, 4_TILED_DG2_RC_CCS) },
{ DRM_MODIFIER_INTEL(4_TILED_DG2_MC_CCS, 4_TILED_DG2_MC_CCS) },
{ DRM_MODIFIER_INTEL(4_TILED_DG2_RC_CCS_CC, 4_TILED_DG2_RC_CCS_CC) },
{ DRM_MODIFIER_INTEL(4_TILED_MTL_RC_CCS, 4_TILED_MTL_RC_CCS) },
{ DRM_MODIFIER_INTEL(4_TILED_MTL_MC_CCS, 4_TILED_MTL_MC_CCS) },
{ DRM_MODIFIER_INTEL(4_TILED_MTL_RC_CCS_CC, 4_TILED_MTL_RC_CCS_CC) },
{ DRM_MODIFIER(SAMSUNG, 64_32_TILE, 64_32_TILE) },
{ DRM_MODIFIER(SAMSUNG, 16_16_TILE, 16_16_TILE) },
{ DRM_MODIFIER(QCOM, COMPRESSED, COMPRESSED) },

View File

@ -94,6 +94,9 @@ extern "C" {
*
* %AMDGPU_GEM_DOMAIN_OA Ordered append, used by 3D or Compute engines
* for appending data.
*
* %AMDGPU_GEM_DOMAIN_DOORBELL Doorbell. It is an MMIO region for
* signalling user mode queues.
*/
#define AMDGPU_GEM_DOMAIN_CPU 0x1
#define AMDGPU_GEM_DOMAIN_GTT 0x2
@ -101,12 +104,14 @@ extern "C" {
#define AMDGPU_GEM_DOMAIN_GDS 0x8
#define AMDGPU_GEM_DOMAIN_GWS 0x10
#define AMDGPU_GEM_DOMAIN_OA 0x20
#define AMDGPU_GEM_DOMAIN_DOORBELL 0x40
#define AMDGPU_GEM_DOMAIN_MASK (AMDGPU_GEM_DOMAIN_CPU | \
AMDGPU_GEM_DOMAIN_GTT | \
AMDGPU_GEM_DOMAIN_VRAM | \
AMDGPU_GEM_DOMAIN_GDS | \
AMDGPU_GEM_DOMAIN_GWS | \
AMDGPU_GEM_DOMAIN_OA)
AMDGPU_GEM_DOMAIN_OA | \
AMDGPU_GEM_DOMAIN_DOORBELL)
/* Flag that CPU access will be required for the case of VRAM domain */
#define AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED (1 << 0)
@ -140,6 +145,32 @@ extern "C" {
* not require GTT memory accounting
*/
#define AMDGPU_GEM_CREATE_PREEMPTIBLE (1 << 11)
/* Flag that BO can be discarded under memory pressure without keeping the
* content.
*/
#define AMDGPU_GEM_CREATE_DISCARDABLE (1 << 12)
/* Flag that BO is shared coherently between multiple devices or CPU threads.
* May depend on GPU instructions to flush caches to system scope explicitly.
*
* This influences the choice of MTYPE in the PTEs on GFXv9 and later GPUs and
* may override the MTYPE selected in AMDGPU_VA_OP_MAP.
*/
#define AMDGPU_GEM_CREATE_COHERENT (1 << 13)
/* Flag that BO should not be cached by GPU. Coherent without having to flush
* GPU caches explicitly
*
* This influences the choice of MTYPE in the PTEs on GFXv9 and later GPUs and
* may override the MTYPE selected in AMDGPU_VA_OP_MAP.
*/
#define AMDGPU_GEM_CREATE_UNCACHED (1 << 14)
/* Flag that BO should be coherent across devices when using device-level
* atomics. May depend on GPU instructions to flush caches to device scope
* explicitly, promoting them to system scope automatically.
*
* This influences the choice of MTYPE in the PTEs on GFXv9 and later GPUs and
* may override the MTYPE selected in AMDGPU_VA_OP_MAP.
*/
#define AMDGPU_GEM_CREATE_EXT_COHERENT (1 << 15)
struct drm_amdgpu_gem_create_in {
/** the requested memory size */
@ -218,15 +249,17 @@ union drm_amdgpu_bo_list {
/* unknown cause */
#define AMDGPU_CTX_UNKNOWN_RESET 3
/* indicate gpu reset occured after ctx created */
/* indicate gpu reset occurred after ctx created */
#define AMDGPU_CTX_QUERY2_FLAGS_RESET (1<<0)
/* indicate vram lost occured after ctx created */
/* indicate vram lost occurred after ctx created */
#define AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST (1<<1)
/* indicate some job from this context once cause gpu hang */
#define AMDGPU_CTX_QUERY2_FLAGS_GUILTY (1<<2)
/* indicate some errors are detected by RAS */
#define AMDGPU_CTX_QUERY2_FLAGS_RAS_CE (1<<3)
#define AMDGPU_CTX_QUERY2_FLAGS_RAS_UE (1<<4)
/* indicate that the reset hasn't completed yet */
#define AMDGPU_CTX_QUERY2_FLAGS_RESET_IN_PROGRESS (1<<5)
/* Context priority level */
#define AMDGPU_CTX_PRIORITY_UNSET -2048
@ -529,6 +562,8 @@ struct drm_amdgpu_gem_op {
#define AMDGPU_VM_MTYPE_UC (4 << 5)
/* Use Read Write MTYPE instead of default MTYPE */
#define AMDGPU_VM_MTYPE_RW (5 << 5)
/* don't allocate MALL */
#define AMDGPU_VM_PAGE_NOALLOC (1 << 9)
struct drm_amdgpu_gem_va {
/** GEM object handle */
@ -559,7 +594,8 @@ struct drm_amdgpu_gem_va {
*/
#define AMDGPU_HW_IP_VCN_ENC 7
#define AMDGPU_HW_IP_VCN_JPEG 8
#define AMDGPU_HW_IP_NUM 9
#define AMDGPU_HW_IP_VPE 9
#define AMDGPU_HW_IP_NUM 10
#define AMDGPU_HW_IP_INSTANCE_MAX_COUNT 1
@ -572,6 +608,7 @@ struct drm_amdgpu_gem_va {
#define AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES 0x07
#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT 0x08
#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL 0x09
#define AMDGPU_CHUNK_ID_CP_GFX_SHADOW 0x0a
struct drm_amdgpu_cs_chunk {
__u32 chunk_id;
@ -688,6 +725,15 @@ struct drm_amdgpu_cs_chunk_data {
};
};
#define AMDGPU_CS_CHUNK_CP_GFX_SHADOW_FLAGS_INIT_SHADOW 0x1
struct drm_amdgpu_cs_chunk_cp_gfx_shadow {
__u64 shadow_va;
__u64 csa_va;
__u64 gds_va;
__u64 flags;
};
/*
* Query h/w info: Flag that this is integrated (a.h.a. fusion) GPU
*
@ -695,6 +741,7 @@ struct drm_amdgpu_cs_chunk_data {
#define AMDGPU_IDS_FLAGS_FUSION 0x1
#define AMDGPU_IDS_FLAGS_PREEMPTION 0x2
#define AMDGPU_IDS_FLAGS_TMZ 0x4
#define AMDGPU_IDS_FLAGS_CONFORMANT_TRUNC_COORD 0x8
/* indicate if acceleration can be working */
#define AMDGPU_INFO_ACCEL_WORKING 0x00
@ -747,6 +794,20 @@ struct drm_amdgpu_cs_chunk_data {
#define AMDGPU_INFO_FW_DMCUB 0x14
/* Subquery id: Query TOC firmware version */
#define AMDGPU_INFO_FW_TOC 0x15
/* Subquery id: Query CAP firmware version */
#define AMDGPU_INFO_FW_CAP 0x16
/* Subquery id: Query GFX RLCP firmware version */
#define AMDGPU_INFO_FW_GFX_RLCP 0x17
/* Subquery id: Query GFX RLCV firmware version */
#define AMDGPU_INFO_FW_GFX_RLCV 0x18
/* Subquery id: Query MES_KIQ firmware version */
#define AMDGPU_INFO_FW_MES_KIQ 0x19
/* Subquery id: Query MES firmware version */
#define AMDGPU_INFO_FW_MES 0x1a
/* Subquery id: Query IMU firmware version */
#define AMDGPU_INFO_FW_IMU 0x1b
/* Subquery id: Query VPE firmware version */
#define AMDGPU_INFO_FW_VPE 0x1c
/* number of bytes moved for TTM migration */
#define AMDGPU_INFO_NUM_BYTES_MOVED 0x0f
@ -800,6 +861,10 @@ struct drm_amdgpu_cs_chunk_data {
#define AMDGPU_INFO_SENSOR_STABLE_PSTATE_GFX_SCLK 0x8
/* Subquery id: Query GPU stable pstate memory clock */
#define AMDGPU_INFO_SENSOR_STABLE_PSTATE_GFX_MCLK 0x9
/* Subquery id: Query GPU peak pstate shader clock */
#define AMDGPU_INFO_SENSOR_PEAK_PSTATE_GFX_SCLK 0xa
/* Subquery id: Query GPU peak pstate memory clock */
#define AMDGPU_INFO_SENSOR_PEAK_PSTATE_GFX_MCLK 0xb
/* Number of VRAM page faults on CPU access. */
#define AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS 0x1E
#define AMDGPU_INFO_VRAM_LOST_COUNTER 0x1F
@ -839,6 +904,10 @@ struct drm_amdgpu_cs_chunk_data {
#define AMDGPU_INFO_VIDEO_CAPS_DECODE 0
/* Subquery id: Encode */
#define AMDGPU_INFO_VIDEO_CAPS_ENCODE 1
/* Query the max number of IBs per gang per submission */
#define AMDGPU_INFO_MAX_IBS 0x22
/* query last page fault info */
#define AMDGPU_INFO_GPUVM_FAULT 0x23
#define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0
#define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff
@ -990,6 +1059,8 @@ struct drm_amdgpu_info_vbios {
#define AMDGPU_VRAM_TYPE_DDR4 8
#define AMDGPU_VRAM_TYPE_GDDR6 9
#define AMDGPU_VRAM_TYPE_DDR5 10
#define AMDGPU_VRAM_TYPE_LPDDR4 11
#define AMDGPU_VRAM_TYPE_LPDDR5 12
struct drm_amdgpu_info_device {
/** PCI Device ID */
@ -1015,7 +1086,8 @@ struct drm_amdgpu_info_device {
__u32 enabled_rb_pipes_mask;
__u32 num_rb_pipes;
__u32 num_hw_gfx_contexts;
__u32 _pad;
/* PCIe version (the smaller of the GPU and the CPU/motherboard) */
__u32 pcie_gen;
__u64 ids_flags;
/** Starting virtual address for UMDs. */
__u64 virtual_address_offset;
@ -1062,7 +1134,8 @@ struct drm_amdgpu_info_device {
__u32 gs_prim_buffer_depth;
/* max gs wavefront per vgt*/
__u32 max_gs_waves_per_vgt;
__u32 _pad1;
/* PCIe number of lanes (the smaller of the GPU and the CPU/motherboard) */
__u32 pcie_num_lanes;
/* always on cu bitmap */
__u32 cu_ao_bitmap[4][4];
/** Starting high virtual address for UMDs. */
@ -1073,6 +1146,26 @@ struct drm_amdgpu_info_device {
__u32 pa_sc_tile_steering_override;
/* disabled TCCs */
__u64 tcc_disabled_mask;
__u64 min_engine_clock;
__u64 min_memory_clock;
/* The following fields are only set on gfx11+, older chips set 0. */
__u32 tcp_cache_size; /* AKA GL0, VMEM cache */
__u32 num_sqc_per_wgp;
__u32 sqc_data_cache_size; /* AKA SMEM cache */
__u32 sqc_inst_cache_size;
__u32 gl1c_cache_size;
__u32 gl2c_cache_size;
__u64 mall_size; /* AKA infinity cache */
/* high 32 bits of the rb pipes mask */
__u32 enabled_rb_pipes_mask_hi;
/* shadow area size for gfx11 */
__u32 shadow_size;
/* shadow area base virtual alignment for gfx11 */
__u32 shadow_alignment;
/* context save area size for gfx11 */
__u32 csa_size;
/* context save area base virtual alignment for gfx11 */
__u32 csa_alignment;
};
struct drm_amdgpu_info_hw_ip {
@ -1087,7 +1180,8 @@ struct drm_amdgpu_info_hw_ip {
__u32 ib_size_alignment;
/** Bitmask of available rings. Bit 0 means ring 0, etc. */
__u32 available_rings;
__u32 _pad;
/** version info: bits 23:16 major, 15:8 minor, 7:0 revision */
__u32 ip_discovery_version;
};
struct drm_amdgpu_info_num_handles {
@ -1139,6 +1233,20 @@ struct drm_amdgpu_info_video_caps {
struct drm_amdgpu_info_video_codec_info codec_info[AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_COUNT];
};
#define AMDGPU_VMHUB_TYPE_MASK 0xff
#define AMDGPU_VMHUB_TYPE_SHIFT 0
#define AMDGPU_VMHUB_TYPE_GFX 0
#define AMDGPU_VMHUB_TYPE_MM0 1
#define AMDGPU_VMHUB_TYPE_MM1 2
#define AMDGPU_VMHUB_IDX_MASK 0xff00
#define AMDGPU_VMHUB_IDX_SHIFT 8
struct drm_amdgpu_info_gpuvm_fault {
__u64 addr;
__u32 status;
__u32 vmhub;
};
/*
* Supported GPU families
*/
@ -1152,7 +1260,12 @@ struct drm_amdgpu_info_video_caps {
#define AMDGPU_FAMILY_RV 142 /* Raven */
#define AMDGPU_FAMILY_NV 143 /* Navi10 */
#define AMDGPU_FAMILY_VGH 144 /* Van Gogh */
#define AMDGPU_FAMILY_GC_11_0_0 145 /* GC 11.0.0 */
#define AMDGPU_FAMILY_YC 146 /* Yellow Carp */
#define AMDGPU_FAMILY_GC_11_0_1 148 /* GC 11.0.1 */
#define AMDGPU_FAMILY_GC_10_3_6 149 /* GC 10.3.6 */
#define AMDGPU_FAMILY_GC_10_3_7 151 /* GC 10.3.7 */
#define AMDGPU_FAMILY_GC_11_5_0 150 /* GC 11.5.0 */
#if defined(__cplusplus)
}

View File

@ -629,8 +629,8 @@ struct drm_gem_open {
/**
* DRM_CAP_VBLANK_HIGH_CRTC
*
* If set to 1, the kernel supports specifying a CRTC index in the high bits of
* &drm_wait_vblank_request.type.
* If set to 1, the kernel supports specifying a :ref:`CRTC index<crtc_index>`
* in the high bits of &drm_wait_vblank_request.type.
*
* Starting kernel version 2.6.39, this capability is always set to 1.
*/
@ -667,8 +667,11 @@ struct drm_gem_open {
* Bitfield of supported PRIME sharing capabilities. See &DRM_PRIME_CAP_IMPORT
* and &DRM_PRIME_CAP_EXPORT.
*
* PRIME buffers are exposed as dma-buf file descriptors. See
* Documentation/gpu/drm-mm.rst, section "PRIME Buffer Sharing".
* Starting from kernel version 6.6, both &DRM_PRIME_CAP_IMPORT and
* &DRM_PRIME_CAP_EXPORT are always advertised.
*
* PRIME buffers are exposed as dma-buf file descriptors.
* See :ref:`prime_buffer_sharing`.
*/
#define DRM_CAP_PRIME 0x5
/**
@ -676,6 +679,8 @@ struct drm_gem_open {
*
* If this bit is set in &DRM_CAP_PRIME, the driver supports importing PRIME
* buffers via the &DRM_IOCTL_PRIME_FD_TO_HANDLE ioctl.
*
* Starting from kernel version 6.6, this bit is always set in &DRM_CAP_PRIME.
*/
#define DRM_PRIME_CAP_IMPORT 0x1
/**
@ -683,6 +688,8 @@ struct drm_gem_open {
*
* If this bit is set in &DRM_CAP_PRIME, the driver supports exporting PRIME
* buffers via the &DRM_IOCTL_PRIME_HANDLE_TO_FD ioctl.
*
* Starting from kernel version 6.6, this bit is always set in &DRM_CAP_PRIME.
*/
#define DRM_PRIME_CAP_EXPORT 0x2
/**
@ -700,7 +707,8 @@ struct drm_gem_open {
/**
* DRM_CAP_ASYNC_PAGE_FLIP
*
* If set to 1, the driver supports &DRM_MODE_PAGE_FLIP_ASYNC.
* If set to 1, the driver supports &DRM_MODE_PAGE_FLIP_ASYNC for legacy
* page-flips.
*/
#define DRM_CAP_ASYNC_PAGE_FLIP 0x7
/**
@ -750,17 +758,23 @@ struct drm_gem_open {
/**
* DRM_CAP_SYNCOBJ
*
* If set to 1, the driver supports sync objects. See
* Documentation/gpu/drm-mm.rst, section "DRM Sync Objects".
* If set to 1, the driver supports sync objects. See :ref:`drm_sync_objects`.
*/
#define DRM_CAP_SYNCOBJ 0x13
/**
* DRM_CAP_SYNCOBJ_TIMELINE
*
* If set to 1, the driver supports timeline operations on sync objects. See
* Documentation/gpu/drm-mm.rst, section "DRM Sync Objects".
* :ref:`drm_sync_objects`.
*/
#define DRM_CAP_SYNCOBJ_TIMELINE 0x14
/**
* DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP
*
* If set to 1, the driver supports &DRM_MODE_PAGE_FLIP_ASYNC for atomic
* commits.
*/
#define DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP 0x15
/* DRM_IOCTL_GET_CAP ioctl argument type */
struct drm_get_cap {
@ -830,6 +844,31 @@ struct drm_get_cap {
*/
#define DRM_CLIENT_CAP_WRITEBACK_CONNECTORS 5
/**
* DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT
*
* Drivers for para-virtualized hardware (e.g. vmwgfx, qxl, virtio and
* virtualbox) have additional restrictions for cursor planes (thus
* making cursor planes on those drivers not truly universal,) e.g.
* they need cursor planes to act like one would expect from a mouse
* cursor and have correctly set hotspot properties.
* If this client cap is not set the DRM core will hide cursor plane on
* those virtualized drivers because not setting it implies that the
* client is not capable of dealing with those extra restictions.
* Clients which do set cursor hotspot and treat the cursor plane
* like a mouse cursor should set this property.
* The client must enable &DRM_CLIENT_CAP_ATOMIC first.
*
* Setting this property on drivers which do not special case
* cursor planes (i.e. non-virtualized drivers) will return
* EOPNOTSUPP, which can be used by userspace to gauge
* requirements of the hardware/drivers they're running on.
*
* This capability is always supported for atomic-capable virtualized
* drivers starting from kernel version 6.6.
*/
#define DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT 6
/* DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */
struct drm_set_client_cap {
__u64 capability;
@ -881,6 +920,7 @@ struct drm_syncobj_transfer {
#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0)
#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1)
#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE (1 << 2) /* wait for time point to become available */
#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_DEADLINE (1 << 3) /* set fence deadline to deadline_nsec */
struct drm_syncobj_wait {
__u64 handles;
/* absolute timeout */
@ -889,6 +929,14 @@ struct drm_syncobj_wait {
__u32 flags;
__u32 first_signaled; /* only valid when not waiting all */
__u32 pad;
/**
* @deadline_nsec - fence deadline hint
*
* Deadline hint, in absolute CLOCK_MONOTONIC, to set on backing
* fence(s) if the DRM_SYNCOBJ_WAIT_FLAGS_WAIT_DEADLINE flag is
* set.
*/
__u64 deadline_nsec;
};
struct drm_syncobj_timeline_wait {
@ -901,6 +949,35 @@ struct drm_syncobj_timeline_wait {
__u32 flags;
__u32 first_signaled; /* only valid when not waiting all */
__u32 pad;
/**
* @deadline_nsec - fence deadline hint
*
* Deadline hint, in absolute CLOCK_MONOTONIC, to set on backing
* fence(s) if the DRM_SYNCOBJ_WAIT_FLAGS_WAIT_DEADLINE flag is
* set.
*/
__u64 deadline_nsec;
};
/**
* struct drm_syncobj_eventfd
* @handle: syncobj handle.
* @flags: Zero to wait for the point to be signalled, or
* &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE to wait for a fence to be
* available for the point.
* @point: syncobj timeline point (set to zero for binary syncobjs).
* @fd: Existing eventfd to sent events to.
* @pad: Must be zero.
*
* Register an eventfd to be signalled by a syncobj. The eventfd counter will
* be incremented by one.
*/
struct drm_syncobj_eventfd {
__u32 handle;
__u32 flags;
__u64 point;
__s32 fd;
__u32 pad;
};
@ -966,6 +1043,19 @@ extern "C" {
#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
/**
* DRM_IOCTL_GEM_CLOSE - Close a GEM handle.
*
* GEM handles are not reference-counted by the kernel. User-space is
* responsible for managing their lifetime. For example, if user-space imports
* the same memory object twice on the same DRM file description, the same GEM
* handle is returned by both imports, and user-space needs to ensure
* &DRM_IOCTL_GEM_CLOSE is performed once only. The same situation can happen
* when a memory object is allocated, then exported and imported again on the
* same DRM file description. The &DRM_IOCTL_MODE_GETFB2 IOCTL is an exception
* and always returns fresh new GEM handles even if an existing GEM handle
* already refers to the same memory object before the IOCTL is performed.
*/
#define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close)
#define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink)
#define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open)
@ -1006,7 +1096,37 @@ extern "C" {
#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock)
#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, struct drm_lock)
/**
* DRM_IOCTL_PRIME_HANDLE_TO_FD - Convert a GEM handle to a DMA-BUF FD.
*
* User-space sets &drm_prime_handle.handle with the GEM handle to export and
* &drm_prime_handle.flags, and gets back a DMA-BUF file descriptor in
* &drm_prime_handle.fd.
*
* The export can fail for any driver-specific reason, e.g. because export is
* not supported for this specific GEM handle (but might be for others).
*
* Support for exporting DMA-BUFs is advertised via &DRM_PRIME_CAP_EXPORT.
*/
#define DRM_IOCTL_PRIME_HANDLE_TO_FD DRM_IOWR(0x2d, struct drm_prime_handle)
/**
* DRM_IOCTL_PRIME_FD_TO_HANDLE - Convert a DMA-BUF FD to a GEM handle.
*
* User-space sets &drm_prime_handle.fd with a DMA-BUF file descriptor to
* import, and gets back a GEM handle in &drm_prime_handle.handle.
* &drm_prime_handle.flags is unused.
*
* If an existing GEM handle refers to the memory object backing the DMA-BUF,
* that GEM handle is returned. Therefore user-space which needs to handle
* arbitrary DMA-BUFs must have a user-space lookup data structure to manually
* reference-count duplicated GEM handles. For more information see
* &DRM_IOCTL_GEM_CLOSE.
*
* The import can fail for any driver-specific reason, e.g. because import is
* only supported for DMA-BUFs allocated on this DRM device.
*
* Support for importing DMA-BUFs is advertised via &DRM_PRIME_CAP_IMPORT.
*/
#define DRM_IOCTL_PRIME_FD_TO_HANDLE DRM_IOWR(0x2e, struct drm_prime_handle)
#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
@ -1044,10 +1164,40 @@ extern "C" {
#define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xAC, struct drm_mode_get_blob)
#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd)
#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd)
/**
* DRM_IOCTL_MODE_RMFB - Remove a framebuffer.
*
* This removes a framebuffer previously added via ADDFB/ADDFB2. The IOCTL
* argument is a framebuffer object ID.
*
* Warning: removing a framebuffer currently in-use on an enabled plane will
* disable that plane. The CRTC the plane is linked to may also be disabled
* (depending on driver capabilities).
*/
#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int)
#define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOWR(0xB0, struct drm_mode_crtc_page_flip)
#define DRM_IOCTL_MODE_DIRTYFB DRM_IOWR(0xB1, struct drm_mode_fb_dirty_cmd)
/**
* DRM_IOCTL_MODE_CREATE_DUMB - Create a new dumb buffer object.
*
* KMS dumb buffers provide a very primitive way to allocate a buffer object
* suitable for scanout and map it for software rendering. KMS dumb buffers are
* not suitable for hardware-accelerated rendering nor video decoding. KMS dumb
* buffers are not suitable to be displayed on any other device than the KMS
* device where they were allocated from. Also see
* :ref:`kms_dumb_buffer_objects`.
*
* The IOCTL argument is a struct drm_mode_create_dumb.
*
* User-space is expected to create a KMS dumb buffer via this IOCTL, then add
* it as a KMS framebuffer via &DRM_IOCTL_MODE_ADDFB and map it via
* &DRM_IOCTL_MODE_MAP_DUMB.
*
* &DRM_CAP_DUMB_BUFFER indicates whether this IOCTL is supported.
* &DRM_CAP_DUMB_PREFERRED_DEPTH and &DRM_CAP_DUMB_PREFER_SHADOW indicate
* driver preferences for dumb buffers.
*/
#define DRM_IOCTL_MODE_CREATE_DUMB DRM_IOWR(0xB2, struct drm_mode_create_dumb)
#define DRM_IOCTL_MODE_MAP_DUMB DRM_IOWR(0xB3, struct drm_mode_map_dumb)
#define DRM_IOCTL_MODE_DESTROY_DUMB DRM_IOWR(0xB4, struct drm_mode_destroy_dumb)
@ -1080,8 +1230,58 @@ extern "C" {
#define DRM_IOCTL_SYNCOBJ_TRANSFER DRM_IOWR(0xCC, struct drm_syncobj_transfer)
#define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL DRM_IOWR(0xCD, struct drm_syncobj_timeline_array)
/**
* DRM_IOCTL_MODE_GETFB2 - Get framebuffer metadata.
*
* This queries metadata about a framebuffer. User-space fills
* &drm_mode_fb_cmd2.fb_id as the input, and the kernels fills the rest of the
* struct as the output.
*
* If the client is DRM master or has &CAP_SYS_ADMIN, &drm_mode_fb_cmd2.handles
* will be filled with GEM buffer handles. Fresh new GEM handles are always
* returned, even if another GEM handle referring to the same memory object
* already exists on the DRM file description. The caller is responsible for
* removing the new handles, e.g. via the &DRM_IOCTL_GEM_CLOSE IOCTL. The same
* new handle will be returned for multiple planes in case they use the same
* memory object. Planes are valid until one has a zero handle -- this can be
* used to compute the number of planes.
*
* Otherwise, &drm_mode_fb_cmd2.handles will be zeroed and planes are valid
* until one has a zero &drm_mode_fb_cmd2.pitches.
*
* If the framebuffer has a format modifier, &DRM_MODE_FB_MODIFIERS will be set
* in &drm_mode_fb_cmd2.flags and &drm_mode_fb_cmd2.modifier will contain the
* modifier. Otherwise, user-space must ignore &drm_mode_fb_cmd2.modifier.
*
* To obtain DMA-BUF FDs for each plane without leaking GEM handles, user-space
* can export each handle via &DRM_IOCTL_PRIME_HANDLE_TO_FD, then immediately
* close each unique handle via &DRM_IOCTL_GEM_CLOSE, making sure to not
* double-close handles which are specified multiple times in the array.
*/
#define DRM_IOCTL_MODE_GETFB2 DRM_IOWR(0xCE, struct drm_mode_fb_cmd2)
#define DRM_IOCTL_SYNCOBJ_EVENTFD DRM_IOWR(0xCF, struct drm_syncobj_eventfd)
/**
* DRM_IOCTL_MODE_CLOSEFB - Close a framebuffer.
*
* This closes a framebuffer previously added via ADDFB/ADDFB2. The IOCTL
* argument is a framebuffer object ID.
*
* This IOCTL is similar to &DRM_IOCTL_MODE_RMFB, except it doesn't disable
* planes and CRTCs. As long as the framebuffer is used by a plane, it's kept
* alive. When the plane no longer uses the framebuffer (because the
* framebuffer is replaced with another one, or the plane is disabled), the
* framebuffer is cleaned up.
*
* This is useful to implement flicker-free transitions between two processes.
*
* Depending on the threat model, user-space may want to ensure that the
* framebuffer doesn't expose any sensitive user information: closed
* framebuffers attached to a plane can be read back by the next DRM master.
*/
#define DRM_IOCTL_MODE_CLOSEFB DRM_IOWR(0xD0, struct drm_mode_closefb)
/*
* Device specific ioctls should only be in their respective headers
* The device specific ioctl range is from 0x40 to 0x9f.
@ -1093,25 +1293,50 @@ extern "C" {
#define DRM_COMMAND_BASE 0x40
#define DRM_COMMAND_END 0xA0
/*
* Header for events written back to userspace on the drm fd. The
* type defines the type of event, the length specifies the total
* length of the event (including the header), and user_data is
* typically a 64 bit value passed with the ioctl that triggered the
* event. A read on the drm fd will always only return complete
* events, that is, if for example the read buffer is 100 bytes, and
* there are two 64 byte events pending, only one will be returned.
/**
* struct drm_event - Header for DRM events
* @type: event type.
* @length: total number of payload bytes (including header).
*
* Event types 0 - 0x7fffffff are generic drm events, 0x80000000 and
* up are chipset specific.
* This struct is a header for events written back to user-space on the DRM FD.
* A read on the DRM FD will always only return complete events: e.g. if the
* read buffer is 100 bytes large and there are two 64 byte events pending,
* only one will be returned.
*
* Event types 0 - 0x7fffffff are generic DRM events, 0x80000000 and
* up are chipset specific. Generic DRM events include &DRM_EVENT_VBLANK,
* &DRM_EVENT_FLIP_COMPLETE and &DRM_EVENT_CRTC_SEQUENCE.
*/
struct drm_event {
__u32 type;
__u32 length;
};
/**
* DRM_EVENT_VBLANK - vertical blanking event
*
* This event is sent in response to &DRM_IOCTL_WAIT_VBLANK with the
* &_DRM_VBLANK_EVENT flag set.
*
* The event payload is a struct drm_event_vblank.
*/
#define DRM_EVENT_VBLANK 0x01
/**
* DRM_EVENT_FLIP_COMPLETE - page-flip completion event
*
* This event is sent in response to an atomic commit or legacy page-flip with
* the &DRM_MODE_PAGE_FLIP_EVENT flag set.
*
* The event payload is a struct drm_event_vblank.
*/
#define DRM_EVENT_FLIP_COMPLETE 0x02
/**
* DRM_EVENT_CRTC_SEQUENCE - CRTC sequence event
*
* This event is sent in response to &DRM_IOCTL_CRTC_QUEUE_SEQUENCE.
*
* The event payload is a struct drm_event_crtc_sequence.
*/
#define DRM_EVENT_CRTC_SEQUENCE 0x03
struct drm_event_vblank {

View File

@ -88,6 +88,18 @@ extern "C" {
*
* The authoritative list of format modifier codes is found in
* `include/uapi/drm/drm_fourcc.h`
*
* Open Source User Waiver
* -----------------------
*
* Because this is the authoritative source for pixel formats and modifiers
* referenced by GL, Vulkan extensions and other standards and hence used both
* by open source and closed source driver stacks, the usual requirement for an
* upstream in-kernel or open source userspace user does not apply.
*
* To ensure, as much as feasible, compatibility across stacks and avoid
* confusion with incompatible enumerations stakeholders for all relevant driver
* stacks should approve additions.
*/
#define fourcc_code(a, b, c, d) ((__u32)(a) | ((__u32)(b) << 8) | \
@ -311,6 +323,8 @@ extern "C" {
* index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian
*/
#define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */
#define DRM_FORMAT_NV20 fourcc_code('N', 'V', '2', '0') /* 2x1 subsampled Cr:Cb plane */
#define DRM_FORMAT_NV30 fourcc_code('N', 'V', '3', '0') /* non-subsampled Cr:Cb plane */
/*
* 2 plane YCbCr MSB aligned
@ -645,6 +659,49 @@ extern "C" {
*/
#define I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC fourcc_mod_code(INTEL, 12)
/*
* Intel Color Control Surfaces (CCS) for display ver. 14 render compression.
*
* The main surface is tile4 and at plane index 0, the CCS is linear and
* at index 1. A 64B CCS cache line corresponds to an area of 4x1 tiles in
* main surface. In other words, 4 bits in CCS map to a main surface cache
* line pair. The main surface pitch is required to be a multiple of four
* tile4 widths.
*/
#define I915_FORMAT_MOD_4_TILED_MTL_RC_CCS fourcc_mod_code(INTEL, 13)
/*
* Intel Color Control Surfaces (CCS) for display ver. 14 media compression
*
* The main surface is tile4 and at plane index 0, the CCS is linear and
* at index 1. A 64B CCS cache line corresponds to an area of 4x1 tiles in
* main surface. In other words, 4 bits in CCS map to a main surface cache
* line pair. The main surface pitch is required to be a multiple of four
* tile4 widths. For semi-planar formats like NV12, CCS planes follow the
* Y and UV planes i.e., planes 0 and 1 are used for Y and UV surfaces,
* planes 2 and 3 for the respective CCS.
*/
#define I915_FORMAT_MOD_4_TILED_MTL_MC_CCS fourcc_mod_code(INTEL, 14)
/*
* Intel Color Control Surface with Clear Color (CCS) for display ver. 14 render
* compression.
*
* The main surface is tile4 and is at plane index 0 whereas CCS is linear
* and at index 1. The clear color is stored at index 2, and the pitch should
* be ignored. The clear color structure is 256 bits. The first 128 bits
* represents Raw Clear Color Red, Green, Blue and Alpha color each represented
* by 32 bits. The raw clear color is consumed by the 3d engine and generates
* the converted clear color of size 64 bits. The first 32 bits store the Lower
* Converted Clear Color value and the next 32 bits store the Higher Converted
* Clear Color value when applicable. The Converted Clear Color values are
* consumed by the DE. The last 64 bits are used to store Color Discard Enable
* and Depth Clear Value Valid which are ignored by the DE. A CCS cache line
* corresponds to an area of 4x1 tiles in the main surface. The main surface
* pitch is required to be a multiple of 4 tile widths.
*/
#define I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC fourcc_mod_code(INTEL, 15)
/*
* Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks
*

View File

@ -312,16 +312,48 @@ struct drm_mode_set_plane {
__u32 src_w;
};
/**
* struct drm_mode_get_plane - Get plane metadata.
*
* Userspace can perform a GETPLANE ioctl to retrieve information about a
* plane.
*
* To retrieve the number of formats supported, set @count_format_types to zero
* and call the ioctl. @count_format_types will be updated with the value.
*
* To retrieve these formats, allocate an array with the memory needed to store
* @count_format_types formats. Point @format_type_ptr to this array and call
* the ioctl again (with @count_format_types still set to the value returned in
* the first ioctl call).
*/
struct drm_mode_get_plane {
/**
* @plane_id: Object ID of the plane whose information should be
* retrieved. Set by caller.
*/
__u32 plane_id;
/** @crtc_id: Object ID of the current CRTC. */
__u32 crtc_id;
/** @fb_id: Object ID of the current fb. */
__u32 fb_id;
/**
* @possible_crtcs: Bitmask of CRTC's compatible with the plane. CRTC's
* are created and they receive an index, which corresponds to their
* position in the bitmask. Bit N corresponds to
* :ref:`CRTC index<crtc_index>` N.
*/
__u32 possible_crtcs;
/** @gamma_size: Never used. */
__u32 gamma_size;
/** @count_format_types: Number of formats. */
__u32 count_format_types;
/**
* @format_type_ptr: Pointer to ``__u32`` array of formats that are
* supported by the plane. These formats do not require modifiers.
*/
__u64 format_type_ptr;
};
@ -456,6 +488,9 @@ struct drm_mode_get_connector {
* This is not an object ID. This is a per-type connector number. Each
* (type, type_id) combination is unique across all connectors of a DRM
* device.
*
* The (type, type_id) combination is not a stable identifier: the
* type_id can change depending on the driver probe order.
*/
__u32 connector_type_id;
@ -509,22 +544,74 @@ struct drm_mode_get_connector {
*/
#define DRM_MODE_PROP_ATOMIC 0x80000000
/**
* struct drm_mode_property_enum - Description for an enum/bitfield entry.
* @value: numeric value for this enum entry.
* @name: symbolic name for this enum entry.
*
* See struct drm_property_enum for details.
*/
struct drm_mode_property_enum {
__u64 value;
char name[DRM_PROP_NAME_LEN];
};
/**
* struct drm_mode_get_property - Get property metadata.
*
* User-space can perform a GETPROPERTY ioctl to retrieve information about a
* property. The same property may be attached to multiple objects, see
* "Modeset Base Object Abstraction".
*
* The meaning of the @values_ptr field changes depending on the property type.
* See &drm_property.flags for more details.
*
* The @enum_blob_ptr and @count_enum_blobs fields are only meaningful when the
* property has the type &DRM_MODE_PROP_ENUM or &DRM_MODE_PROP_BITMASK. For
* backwards compatibility, the kernel will always set @count_enum_blobs to
* zero when the property has the type &DRM_MODE_PROP_BLOB. User-space must
* ignore these two fields if the property has a different type.
*
* User-space is expected to retrieve values and enums by performing this ioctl
* at least twice: the first time to retrieve the number of elements, the
* second time to retrieve the elements themselves.
*
* To retrieve the number of elements, set @count_values and @count_enum_blobs
* to zero, then call the ioctl. @count_values will be updated with the number
* of elements. If the property has the type &DRM_MODE_PROP_ENUM or
* &DRM_MODE_PROP_BITMASK, @count_enum_blobs will be updated as well.
*
* To retrieve the elements themselves, allocate an array for @values_ptr and
* set @count_values to its capacity. If the property has the type
* &DRM_MODE_PROP_ENUM or &DRM_MODE_PROP_BITMASK, allocate an array for
* @enum_blob_ptr and set @count_enum_blobs to its capacity. Calling the ioctl
* again will fill the arrays.
*/
struct drm_mode_get_property {
__u64 values_ptr; /* values and blob lengths */
__u64 enum_blob_ptr; /* enum and blob id ptrs */
/** @values_ptr: Pointer to a ``__u64`` array. */
__u64 values_ptr;
/** @enum_blob_ptr: Pointer to a struct drm_mode_property_enum array. */
__u64 enum_blob_ptr;
/**
* @prop_id: Object ID of the property which should be retrieved. Set
* by the caller.
*/
__u32 prop_id;
/**
* @flags: ``DRM_MODE_PROP_*`` bitfield. See &drm_property.flags for
* a definition of the flags.
*/
__u32 flags;
/**
* @name: Symbolic property name. User-space should use this field to
* recognize properties.
*/
char name[DRM_PROP_NAME_LEN];
/** @count_values: Number of elements in @values_ptr. */
__u32 count_values;
/* This is only used to count enum values, not blobs. The _blobs is
* simply because of a historical reason, i.e. backwards compat. */
/** @count_enum_blobs: Number of elements in @enum_blob_ptr. */
__u32 count_enum_blobs;
};
@ -579,41 +666,73 @@ struct drm_mode_fb_cmd {
#define DRM_MODE_FB_INTERLACED (1<<0) /* for interlaced framebuffers */
#define DRM_MODE_FB_MODIFIERS (1<<1) /* enables ->modifer[] */
/**
* struct drm_mode_fb_cmd2 - Frame-buffer metadata.
*
* This struct holds frame-buffer metadata. There are two ways to use it:
*
* - User-space can fill this struct and perform a &DRM_IOCTL_MODE_ADDFB2
* ioctl to register a new frame-buffer. The new frame-buffer object ID will
* be set by the kernel in @fb_id.
* - User-space can set @fb_id and perform a &DRM_IOCTL_MODE_GETFB2 ioctl to
* fetch metadata about an existing frame-buffer.
*
* In case of planar formats, this struct allows up to 4 buffer objects with
* offsets and pitches per plane. The pitch and offset order are dictated by
* the format FourCC as defined by ``drm_fourcc.h``, e.g. NV12 is described as:
*
* YUV 4:2:0 image with a plane of 8-bit Y samples followed by an
* interleaved U/V plane containing 8-bit 2x2 subsampled colour difference
* samples.
*
* So it would consist of a Y plane at ``offsets[0]`` and a UV plane at
* ``offsets[1]``.
*
* To accommodate tiled, compressed, etc formats, a modifier can be specified.
* For more information see the "Format Modifiers" section. Note that even
* though it looks like we have a modifier per-plane, we in fact do not. The
* modifier for each plane must be identical. Thus all combinations of
* different data layouts for multi-plane formats must be enumerated as
* separate modifiers.
*
* All of the entries in @handles, @pitches, @offsets and @modifier must be
* zero when unused. Warning, for @offsets and @modifier zero can't be used to
* figure out whether the entry is used or not since it's a valid value (a zero
* offset is common, and a zero modifier is &DRM_FORMAT_MOD_LINEAR).
*/
struct drm_mode_fb_cmd2 {
/** @fb_id: Object ID of the frame-buffer. */
__u32 fb_id;
/** @width: Width of the frame-buffer. */
__u32 width;
/** @height: Height of the frame-buffer. */
__u32 height;
__u32 pixel_format; /* fourcc code from drm_fourcc.h */
__u32 flags; /* see above flags */
/**
* @pixel_format: FourCC format code, see ``DRM_FORMAT_*`` constants in
* ``drm_fourcc.h``.
*/
__u32 pixel_format;
/**
* @flags: Frame-buffer flags (see &DRM_MODE_FB_INTERLACED and
* &DRM_MODE_FB_MODIFIERS).
*/
__u32 flags;
/*
* In case of planar formats, this ioctl allows up to 4
* buffer objects with offsets and pitches per plane.
* The pitch and offset order is dictated by the fourcc,
* e.g. NV12 (https://fourcc.org/yuv.php#NV12) is described as:
*
* YUV 4:2:0 image with a plane of 8 bit Y samples
* followed by an interleaved U/V plane containing
* 8 bit 2x2 subsampled colour difference samples.
*
* So it would consist of Y as offsets[0] and UV as
* offsets[1]. Note that offsets[0] will generally
* be 0 (but this is not required).
*
* To accommodate tiled, compressed, etc formats, a
* modifier can be specified. The default value of zero
* indicates "native" format as specified by the fourcc.
* Vendor specific modifier token. Note that even though
* it looks like we have a modifier per-plane, we in fact
* do not. The modifier for each plane must be identical.
* Thus all combinations of different data layouts for
* multi plane formats must be enumerated as separate
* modifiers.
/**
* @handles: GEM buffer handle, one per plane. Set to 0 if the plane is
* unused. The same handle can be used for multiple planes.
*/
__u32 handles[4];
__u32 pitches[4]; /* pitch for each plane */
__u32 offsets[4]; /* offset of each plane */
__u64 modifier[4]; /* ie, tiling, compress */
/** @pitches: Pitch (aka. stride) in bytes, one per plane. */
__u32 pitches[4];
/** @offsets: Offset into the buffer in bytes, one per plane. */
__u32 offsets[4];
/**
* @modifier: Format modifier, one per plane. See ``DRM_FORMAT_MOD_*``
* constants in ``drm_fourcc.h``. All planes must use the same
* modifier. Ignored unless &DRM_MODE_FB_MODIFIERS is set in @flags.
*/
__u64 modifier[4];
};
#define DRM_MODE_FB_DIRTY_ANNOTATE_COPY 0x01
@ -718,6 +837,11 @@ struct drm_color_ctm {
/*
* Conversion matrix in S31.32 sign-magnitude
* (not two's complement!) format.
*
* out matrix in
* |R| |0 1 2| |R|
* |G| = |3 4 5| x |G|
* |B| |6 7 8| |B|
*/
__u64 matrix[9];
};
@ -762,7 +886,7 @@ struct hdr_metadata_infoframe {
*/
struct {
__u16 x, y;
} display_primaries[3];
} display_primaries[3];
/**
* @white_point: White Point of Colorspace Data.
* These are coded as unsigned 16-bit values in units of
@ -773,7 +897,7 @@ struct hdr_metadata_infoframe {
*/
struct {
__u16 x, y;
} white_point;
} white_point;
/**
* @max_display_mastering_luminance: Max Mastering Display Luminance.
* This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
@ -819,12 +943,40 @@ struct hdr_output_metadata {
};
};
/**
* DRM_MODE_PAGE_FLIP_EVENT
*
* Request that the kernel sends back a vblank event (see
* struct drm_event_vblank) with the &DRM_EVENT_FLIP_COMPLETE type when the
* page-flip is done.
*/
#define DRM_MODE_PAGE_FLIP_EVENT 0x01
/**
* DRM_MODE_PAGE_FLIP_ASYNC
*
* Request that the page-flip is performed as soon as possible, ie. with no
* delay due to waiting for vblank. This may cause tearing to be visible on
* the screen.
*
* When used with atomic uAPI, the driver will return an error if the hardware
* doesn't support performing an asynchronous page-flip for this update.
* User-space should handle this, e.g. by falling back to a regular page-flip.
*
* Note, some hardware might need to perform one last synchronous page-flip
* before being able to switch to asynchronous page-flips. As an exception,
* the driver will return success even though that first page-flip is not
* asynchronous.
*/
#define DRM_MODE_PAGE_FLIP_ASYNC 0x02
#define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4
#define DRM_MODE_PAGE_FLIP_TARGET_RELATIVE 0x8
#define DRM_MODE_PAGE_FLIP_TARGET (DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE | \
DRM_MODE_PAGE_FLIP_TARGET_RELATIVE)
/**
* DRM_MODE_PAGE_FLIP_FLAGS
*
* Bitmask of flags suitable for &drm_mode_crtc_page_flip_target.flags.
*/
#define DRM_MODE_PAGE_FLIP_FLAGS (DRM_MODE_PAGE_FLIP_EVENT | \
DRM_MODE_PAGE_FLIP_ASYNC | \
DRM_MODE_PAGE_FLIP_TARGET)
@ -889,13 +1041,25 @@ struct drm_mode_crtc_page_flip_target {
__u64 user_data;
};
/* create a dumb scanout buffer */
/**
* struct drm_mode_create_dumb - Create a KMS dumb buffer for scanout.
* @height: buffer height in pixels
* @width: buffer width in pixels
* @bpp: bits per pixel
* @flags: must be zero
* @handle: buffer object handle
* @pitch: number of bytes between two consecutive lines
* @size: size of the whole buffer in bytes
*
* User-space fills @height, @width, @bpp and @flags. If the IOCTL succeeds,
* the kernel fills @handle, @pitch and @size.
*/
struct drm_mode_create_dumb {
__u32 height;
__u32 width;
__u32 bpp;
__u32 flags;
/* handle, pitch, size will be returned */
__u32 handle;
__u32 pitch;
__u64 size;
@ -918,11 +1082,53 @@ struct drm_mode_destroy_dumb {
__u32 handle;
};
/* page-flip flags are valid, plus: */
/**
* DRM_MODE_ATOMIC_TEST_ONLY
*
* Do not apply the atomic commit, instead check whether the hardware supports
* this configuration.
*
* See &drm_mode_config_funcs.atomic_check for more details on test-only
* commits.
*/
#define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
/**
* DRM_MODE_ATOMIC_NONBLOCK
*
* Do not block while applying the atomic commit. The &DRM_IOCTL_MODE_ATOMIC
* IOCTL returns immediately instead of waiting for the changes to be applied
* in hardware. Note, the driver will still check that the update can be
* applied before retuning.
*/
#define DRM_MODE_ATOMIC_NONBLOCK 0x0200
/**
* DRM_MODE_ATOMIC_ALLOW_MODESET
*
* Allow the update to result in temporary or transient visible artifacts while
* the update is being applied. Applying the update may also take significantly
* more time than a page flip. All visual artifacts will disappear by the time
* the update is completed, as signalled through the vblank event's timestamp
* (see struct drm_event_vblank).
*
* This flag must be set when the KMS update might cause visible artifacts.
* Without this flag such KMS update will return a EINVAL error. What kind of
* update may cause visible artifacts depends on the driver and the hardware.
* User-space that needs to know beforehand if an update might cause visible
* artifacts can use &DRM_MODE_ATOMIC_TEST_ONLY without
* &DRM_MODE_ATOMIC_ALLOW_MODESET to see if it fails.
*
* To the best of the driver's knowledge, visual artifacts are guaranteed to
* not appear when this flag is not set. Some sinks might display visual
* artifacts outside of the driver's control.
*/
#define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
/**
* DRM_MODE_ATOMIC_FLAGS
*
* Bitfield of flags accepted by the &DRM_IOCTL_MODE_ATOMIC IOCTL in
* &drm_mode_atomic.flags.
*/
#define DRM_MODE_ATOMIC_FLAGS (\
DRM_MODE_PAGE_FLIP_EVENT |\
DRM_MODE_PAGE_FLIP_ASYNC |\
@ -1026,6 +1232,10 @@ struct drm_mode_destroy_blob {
* struct drm_mode_create_lease - Create lease
*
* Lease mode resources, creating another drm_master.
*
* The @object_ids array must reference at least one CRTC, one connector and
* one plane if &DRM_CLIENT_CAP_UNIVERSAL_PLANES is enabled. Alternatively,
* the lease can be completely empty.
*/
struct drm_mode_create_lease {
/** @object_ids: Pointer to array of object ids (__u32) */
@ -1122,6 +1332,16 @@ struct drm_mode_rect {
__s32 y2;
};
/**
* struct drm_mode_closefb
* @fb_id: Framebuffer ID.
* @pad: Must be zero.
*/
struct drm_mode_closefb {
__u32 fb_id;
__u32 pad;
};
#if defined(__cplusplus)
}
#endif

View File

@ -29,7 +29,7 @@ libdrm_intel = library(
],
include_directories : [inc_root, inc_drm],
link_with : libdrm,
dependencies : [dep_pciaccess, dep_pthread_stubs, dep_rt, dep_valgrind, dep_atomic_ops],
dependencies : [dep_pciaccess, dep_threads, dep_rt, dep_valgrind, dep_atomic_ops],
c_args : libdrm_c_args,
gnu_symbol_visibility : 'hidden',
version : '1.0.0',

View File

@ -648,11 +648,11 @@ do {
#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 3UL) == 2UL)
#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 3UL) == 3UL)
#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL))
#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__))
#ifdef HAVE_BIG_ENDIAN
#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24))
#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16))
#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8))
#else /* assume little endian non-intel */
#else /* little endian non-intel */
#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24))
#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16))
#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8))

View File

@ -21,9 +21,9 @@
project(
'libdrm',
['c'],
version : '2.4.115',
version : '2.4.120',
license : 'MIT',
meson_version : '>= 0.53',
meson_version : '>= 0.59',
default_options : ['buildtype=debugoptimized', 'c_std=c11'],
)
@ -40,11 +40,6 @@ with_freedreno_kgsl = get_option('freedreno-kgsl')
with_install_tests = get_option('install-test-programs')
with_tests = get_option('tests')
if ['freebsd', 'dragonfly', 'netbsd'].contains(host_machine.system())
dep_pthread_stubs = dependency('pthread-stubs', version : '>= 0.4')
else
dep_pthread_stubs = []
endif
dep_threads = dependency('threads')
cc = meson.get_compiler('c')
@ -89,109 +84,61 @@ config.set10('HAVE_LIB_ATOMIC_OPS', lib_atomics)
dep_pciaccess = dependency('pciaccess', version : '>= 0.10', required : get_option('intel'))
with_intel = false
_intel = get_option('intel')
if not _intel.disabled()
if _intel.enabled() and not with_atomics
error('libdrm_intel requires atomics.')
else
with_intel = (_intel.enabled() or host_machine.cpu_family().startswith('x86')) and with_atomics and dep_pciaccess.found()
endif
endif
with_intel = get_option('intel') \
.require(with_atomics, error_message : 'libdrm_intel requires atomics') \
.require(dep_pciaccess.found(), error_message : 'libdrm_intel requires libpciaccess') \
.disable_auto_if(not host_machine.cpu_family().startswith('x86')) \
.allowed()
summary('Intel', with_intel)
with_radeon = false
_radeon = get_option('radeon')
if not _radeon.disabled()
if _radeon.enabled() and not with_atomics
error('libdrm_radeon requires atomics.')
endif
with_radeon = with_atomics
endif
with_radeon = get_option('radeon') \
.require(with_atomics, error_message : 'libdrm_radeon requires atomics') \
.allowed()
summary('Radeon', with_radeon)
with_amdgpu = false
_amdgpu = get_option('amdgpu')
if not _amdgpu.disabled()
if _amdgpu.enabled() and not with_atomics
error('libdrm_amdgpu requires atomics.')
endif
with_amdgpu = with_atomics
endif
with_amdgpu = get_option('amdgpu') \
.require(with_atomics, error_message : 'libdrm_amdgpu requires atomics') \
.allowed()
summary('AMDGPU', with_amdgpu)
with_nouveau = false
_nouveau = get_option('nouveau')
if not _nouveau.disabled()
if _nouveau.enabled() and not with_atomics
error('libdrm_nouveau requires atomics.')
endif
with_nouveau = with_atomics
endif
with_nouveau = get_option('nouveau') \
.require(with_atomics, error_message : 'libdrm_nouveau requires atomics') \
.allowed()
summary('Nouveau', with_nouveau)
with_vmwgfx = false
_vmwgfx = get_option('vmwgfx')
if not _vmwgfx.disabled()
with_vmwgfx = true
endif
with_vmwgfx = get_option('vmwgfx').allowed()
summary('vmwgfx', with_vmwgfx)
with_omap = false
_omap = get_option('omap')
if _omap.enabled()
if not with_atomics
error('libdrm_omap requires atomics.')
endif
with_omap = true
endif
with_omap = get_option('omap') \
.require(with_atomics, error_message : 'libdrm_omap requires atomics') \
.enabled()
summary('OMAP', with_omap)
with_freedreno = false
_freedreno = get_option('freedreno')
if not _freedreno.disabled()
if _freedreno.enabled() and not with_atomics
error('libdrm_freedreno requires atomics.')
else
with_freedreno = (_freedreno.enabled() or ['arm', 'aarch64'].contains(host_machine.cpu_family())) and with_atomics
endif
endif
with_freedreno = get_option('freedreno') \
.require(with_atomics, error_message : 'libdrm_freedreno requires atomics') \
.disable_auto_if(not ['arm', 'aarch64'].contains(host_machine.cpu_family())) \
.allowed()
summary('Freedreno', with_freedreno)
summary('Freedreon-kgsl', with_freedreno_kgsl)
with_tegra = false
_tegra = get_option('tegra')
if _tegra.enabled()
if not with_atomics
error('libdrm_tegra requires atomics.')
endif
with_tegra = true
endif
with_tegra = get_option('tegra') \
.require(with_atomics, error_message : 'libdrm_tegra requires atomics') \
.disable_auto_if(not ['arm', 'aarch64'].contains(host_machine.cpu_family())) \
.enabled()
summary('Tegra', with_tegra)
with_etnaviv = false
_etnaviv = get_option('etnaviv')
if not _etnaviv.disabled()
if _etnaviv.enabled() and not with_atomics
error('libdrm_etnaviv requires atomics.')
endif
with_etnaviv = _etnaviv.enabled() or (
with_atomics and [
'loongarch64', 'mips', 'mips64',
'arm', 'aarch64', 'arc',
].contains(host_machine.cpu_family())
)
endif
with_etnaviv = get_option('etnaviv') \
.require(with_atomics, error_message : 'libdrm_etnaviv requires atomics') \
.disable_auto_if(not ['arm', 'aarch64', 'arc', 'mips', 'mips64', 'loongarch64'].contains(host_machine.cpu_family())) \
.allowed()
summary('Etnaviv', with_etnaviv)
with_exynos = get_option('exynos').enabled()
summary('EXYNOS', with_exynos)
with_vc4 = false
_vc4 = get_option('vc4')
if not _vc4.disabled()
with_vc4 = _vc4.enabled() or ['arm', 'aarch64'].contains(host_machine.cpu_family())
endif
with_vc4 = get_option('vc4') \
.disable_auto_if(not ['arm', 'aarch64'].contains(host_machine.cpu_family())) \
.allowed()
summary('VC4', with_vc4)
# Among others FreeBSD does not have a separate dl library.
@ -279,6 +226,11 @@ if with_freedreno_kgsl and not with_freedreno
error('cannot enable freedreno-kgsl without freedreno support')
endif
config.set10('_GNU_SOURCE', true)
if target_machine.endian() == 'big'
config.set('HAVE_BIG_ENDIAN', 1)
endif
config_file = configure_file(
configuration : config,
output : 'config.h',
@ -319,7 +271,7 @@ test(
args : [
'--lib', libdrm,
'--symbols-file', files('core-symbols.txt'),
'--nm', prog_nm.path(),
'--nm', prog_nm.full_path(),
],
)

View File

@ -1,2 +1,2 @@
major=7
minor=12
minor=13

View File

@ -1,2 +1,2 @@
major=1
minor=12
minor=13

View File

@ -60,6 +60,6 @@ test(
args : [
'--lib', libdrm_nouveau,
'--symbols-file', files('nouveau-symbols.txt'),
'--nm', prog_nm.path(),
'--nm', prog_nm.full_path(),
],
)

View File

@ -1,3 +1,4 @@
nouveau_bo_make_global
nouveau_bo_map
nouveau_bo_name_get
nouveau_bo_name_ref

View File

@ -711,7 +711,7 @@ nouveau_bo_wrap_locked(struct nouveau_device *dev, uint32_t handle,
}
static void
nouveau_bo_make_global(struct nouveau_bo_priv *nvbo)
nouveau_nvbo_make_global(struct nouveau_bo_priv *nvbo)
{
if (!nvbo->head.next) {
struct nouveau_device_priv *nvdev = nouveau_device(nvbo->base.device);
@ -722,6 +722,14 @@ nouveau_bo_make_global(struct nouveau_bo_priv *nvbo)
}
}
drm_public void
nouveau_bo_make_global(struct nouveau_bo *bo)
{
struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
nouveau_nvbo_make_global(nvbo);
}
drm_public int
nouveau_bo_wrap(struct nouveau_device *dev, uint32_t handle,
struct nouveau_bo **pbo)
@ -780,7 +788,7 @@ nouveau_bo_name_get(struct nouveau_bo *bo, uint32_t *name)
}
nvbo->name = *name = req.name;
nouveau_bo_make_global(nvbo);
nouveau_nvbo_make_global(nvbo);
}
return 0;
}
@ -830,7 +838,7 @@ nouveau_bo_set_prime(struct nouveau_bo *bo, int *prime_fd)
if (ret)
return ret;
nouveau_bo_make_global(nvbo);
nouveau_nvbo_make_global(nvbo);
return 0;
}

View File

@ -137,6 +137,7 @@ struct nouveau_bo {
int nouveau_bo_new(struct nouveau_device *, uint32_t flags, uint32_t align,
uint64_t size, union nouveau_bo_config *,
struct nouveau_bo **);
void nouveau_bo_make_global(struct nouveau_bo *);
int nouveau_bo_wrap(struct nouveau_device *, uint32_t handle,
struct nouveau_bo **);
int nouveau_bo_name_ref(struct nouveau_device *v, uint32_t name,

View File

@ -25,7 +25,7 @@ libdrm_omap = library(
c_args : libdrm_c_args,
gnu_symbol_visibility : 'hidden',
link_with : libdrm,
dependencies : [dep_pthread_stubs, dep_atomic_ops],
dependencies : [dep_threads, dep_atomic_ops],
version : '1.0.0',
install : true,
)

View File

@ -32,7 +32,7 @@ libdrm_radeon = library(
gnu_symbol_visibility : 'hidden',
include_directories : [inc_root, inc_drm],
link_with : libdrm,
dependencies : [dep_pthread_stubs, dep_atomic_ops],
dependencies : [dep_threads, dep_atomic_ops],
version : '1.0.1',
install : true,
)
@ -65,6 +65,6 @@ test(
args : [
'--lib', libdrm_radeon,
'--symbols-file', files('radeon-symbols.txt'),
'--nm', prog_nm.path(),
'--nm', prog_nm.full_path(),
],
)

View File

@ -2205,6 +2205,7 @@ static int cik_surface_sanity(struct radeon_surface_manager *surf_man,
break;
case RADEON_SURF_MODE_LINEAR_ALIGNED:
default:
*stencil_tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
*tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
}

View File

@ -28,7 +28,7 @@ libdrm_tegra = library(
],
include_directories : [inc_root, inc_drm],
link_with : libdrm,
dependencies : [dep_pthread_stubs, dep_atomic_ops],
dependencies : [dep_threads, dep_atomic_ops],
c_args : libdrm_c_args,
gnu_symbol_visibility : 'hidden',
version : '0.0.0',

View File

@ -30,6 +30,7 @@
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <inttypes.h>
#include "drm.h"
#include "xf86drmMode.h"
@ -175,7 +176,7 @@ int alloc_bo(uint32_t domain, uint64_t size)
resources[num_buffers] = bo;
virtual[num_buffers] = addr;
fprintf(stdout, "Allocated BO number %u at 0x%lx, domain 0x%x, size %lu\n",
fprintf(stdout, "Allocated BO number %u at 0x%" PRIx64 ", domain 0x%x, size %" PRIu64 "\n",
num_buffers++, addr, domain, size);
return 0;
}
@ -273,7 +274,7 @@ int submit_ib(uint32_t from, uint32_t to, uint64_t size, uint32_t count)
delta = stop.tv_nsec + stop.tv_sec * 1000000000UL;
delta -= start.tv_nsec + start.tv_sec * 1000000000UL;
fprintf(stdout, "Submitted %u IBs to copy from %u(%lx) to %u(%lx) %lu bytes took %lu usec\n",
fprintf(stdout, "Submitted %u IBs to copy from %u(%" PRIx64 ") to %u(%" PRIx64 ") %" PRIu64 " bytes took %" PRIu64 " usec\n",
count, from, virtual[from], to, virtual[to], copied, delta / 1000);
return 0;
}
@ -293,7 +294,7 @@ uint64_t parse_size(void)
char ext[2];
ext[0] = 0;
if (sscanf(optarg, "%li%1[kmgKMG]", &size, ext) < 1) {
if (sscanf(optarg, "%" PRIi64 "%1[kmgKMG]", &size, ext) < 1) {
fprintf(stderr, "Can't parse size arg: %s\n", optarg);
exit(EXIT_FAILURE);
}
@ -375,7 +376,7 @@ int main(int argc, char **argv)
next_arg(argc, argv, "Missing buffer size");
size = parse_size();
if (size < getpagesize()) {
fprintf(stderr, "Buffer size to small %lu\n", size);
fprintf(stderr, "Buffer size to small %" PRIu64 "\n", size);
exit(EXIT_FAILURE);
}
r = alloc_bo(domain, size);

View File

@ -296,18 +296,23 @@ static void display_test_suites(void)
/** Help string for command line parameters */
static const char usage[] =
"Usage: %s [-hlpr] [<-s <suite id>> [-t <test id>] [-f]] "
"[-b <pci_bus_id> [-d <pci_device_id>]]\n"
"where:\n"
" l - Display all suites and their tests\n"
" r - Run the tests on render node\n"
" b - Specify device's PCI bus id to run tests\n"
" d - Specify device's PCI device id to run tests (optional)\n"
" p - Display information of AMDGPU devices in system\n"
" f - Force executing inactive suite or test\n"
" h - Display this help\n";
"Usage: %s [-hlpr] [-s <suite id>] [-e <s>[.<t>] [-e ...]] [-t <test id>] [-f] "
"[-b <pci_bus_id>] [-d <pci_device_id>]\n"
"Where,\n"
" -b Specify device's PCI bus id to run tests\n"
" -d Specify device's PCI device id to run tests (optional)\n"
" -e <s>[.<t>] Disable test <t> of suite <s>. If only <s> is given, then disable\n"
" the whole suite. Can be specified more than once on the command line\n"
" to disable multiple tests or suites.\n"
" -f Force executing inactive suite or test\n"
" -h Display this help\n"
" -l Display all test suites and their tests\n"
" -p Display information of AMDGPU devices in system\n"
" -r Run the tests on render node\n"
" -s <s> Enable only test suite <s>\n"
" -t <t> Enable only test <t> of test suite <s>\n";
/** Specified options strings for getopt */
static const char options[] = "hlrps:t:b:d:f";
static const char options[] = "hlrps:t:e:b:d:f";
/* Open AMD devices.
* Return the number of AMD device opened.
@ -662,6 +667,48 @@ char *amdgpu_get_device_from_fd(int fd)
#endif
}
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(_A) (sizeof(_A)/sizeof(_A[0]))
#endif
static void amdgpu_test_disable(long suite, long test)
{
const char *suite_name;
if (suite < 1)
return;
/* The array is 0-based, so subract 1. */
suite--;
if (suite >= ARRAY_SIZE(suites) - 1)
return;
suite_name = suites[suite].pName;
if (test < 1) {
fprintf(stderr, "Deactivating suite %s\n", suite_name);
amdgpu_set_suite_active(suite_name, CU_FALSE);
} else {
int ii;
/* The array is 0-based so subtract 1. */
test--;
for (ii = 0; suites[suite].pTests[ii].pName; ii++) {
if (ii == test) {
fprintf(stderr, "Deactivating %s:%s\n",
suite_name,
suites[suite].pTests[ii].pName);
amdgpu_set_test_active(suite_name,
suites[suite].pTests[ii].pName,
CU_FALSE);
break;
}
}
if (suites[suite].pTests[ii].pName == NULL)
fprintf(stderr, "No such suite.test %ld.%ld\n", suite, test);
}
}
/* The main() function for setting up and running the tests.
* Returns a CUE_SUCCESS on successful running, another
* CUnit error code on failure.
@ -680,48 +727,21 @@ int main(int argc, char **argv)
int display_list = 0;
int force_run = 0;
for (i = 0; i < MAX_CARDS_SUPPORTED; i++)
drm_amdgpu[i] = -1;
/* Parse command line string */
/* Parse command line string.
* Process various command line options as early as possible.
*/
opterr = 0; /* Do not print error messages from getopt */
while ((c = getopt(argc, argv, options)) != -1) {
switch (c) {
case 'l':
display_list = 1;
break;
case 's':
suite_id = atoi(optarg);
break;
case 't':
test_id = atoi(optarg);
break;
case 'b':
pci_bus_id = atoi(optarg);
break;
case 'd':
sscanf(optarg, "%x", &pci_device_id);
break;
case 'p':
display_devices = 1;
break;
case 'r':
open_render_node = 1;
break;
case 'f':
force_run = 1;
break;
case '?':
case 'h':
fprintf(stderr, usage, argv[0]);
exit(EXIT_SUCCESS);
default:
fprintf(stderr, usage, argv[0]);
exit(EXIT_FAILURE);
}
}
for (i = 0; i < MAX_CARDS_SUPPORTED; i++)
drm_amdgpu[i] = -1;
if (amdgpu_open_devices(open_render_node) <= 0) {
perror("Cannot open AMDGPU device");
exit(EXIT_FAILURE);
@ -732,12 +752,37 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE);
}
/* Parse command line string */
opterr = 0; /* Do not print error messages from getopt */
optind = 1;
while ((c = getopt(argc, argv, options)) != -1) {
switch (c) {
case 'p':
display_devices = 1;
break;
}
}
if (display_devices) {
amdgpu_print_devices();
amdgpu_close_devices();
exit(EXIT_SUCCESS);
}
/* Parse command line string */
opterr = 0; /* Do not print error messages from getopt */
optind = 1;
while ((c = getopt(argc, argv, options)) != -1) {
switch (c) {
case 'b':
pci_bus_id = atoi(optarg);
break;
case 'd':
sscanf(optarg, "%x", &pci_device_id);
break;
}
}
if (pci_bus_id > 0 || pci_device_id) {
/* A device was specified to run the test */
test_device_index = amdgpu_find_device(pci_bus_id,
@ -780,11 +825,85 @@ int main(int argc, char **argv)
/* Disable suites and individual tests based on misc. conditions */
amdgpu_disable_suites();
/* Parse command line string */
opterr = 0; /* Do not print error messages from getopt */
optind = 1;
while ((c = getopt(argc, argv, options)) != -1) {
switch (c) {
case 'l':
display_list = 1;
break;
}
}
if (display_list) {
display_test_suites();
goto end;
}
/* Parse command line string */
opterr = 0; /* Do not print error messages from getopt */
optind = 1;
while ((c = getopt(argc, argv, options)) != -1) {
long esuite = -1;
long etest = -1;
char *endp;
switch (c) {
case 's':
suite_id = atoi(optarg);
break;
case 't':
test_id = atoi(optarg);
break;
case 'r':
open_render_node = 1;
break;
case 'f':
force_run = 1;
break;
case 'e':
esuite = strtol(optarg, &endp, 0);
if (endp == optarg) {
fprintf(stderr, "No digits given for -e argument\n");
goto end;
} else if (endp && *endp == '.' && esuite > 0) {
char *tt = endp + 1;
etest = strtol(tt, &endp, 0);
if (endp == tt) {
fprintf(stderr, "No digits given for test in -e s.t argument\n");
goto end;
} else if (endp && *endp != '\0') {
fprintf(stderr, "Bad input given for test in -e s.t argument\n");
goto end;
} else if (etest < 1) {
fprintf(stderr, "Test in -e s.t argument cannot be smaller than 1\n");
goto end;
}
} else if (endp && *endp != '\0') {
fprintf(stderr, "Bad input given for suite for -e s argument\n");
goto end;
} else if (esuite < 1) {
fprintf(stderr, "Suite in -e s argument cannot be smaller than 1\n");
goto end;
}
amdgpu_test_disable(esuite, etest);
break;
case 'h':
case 'p':
case 'b':
case 'd':
case 'l':
/* Those have been processed earlier.
*/
break;
case '?':
default:
fprintf(stderr, "Unknown command line option '%c'. Try -h.\n",
c == '?' ? optopt : c);
goto end;
}
}
if (suite_id != -1) { /* If user specify particular suite? */
pSuite = CU_get_suite_by_index((unsigned int) suite_id,
CU_get_registry());

View File

@ -70,6 +70,10 @@ CU_BOOL suite_hotunplug_tests_enable(void)
if (minor_version < 46)
enable = false;
/* skip hotplug test on APUs */
if(device_handle->dev_info.ids_flags & AMDGPU_IDS_FLAGS_FUSION)
enable = false;
if (amdgpu_device_deinitialize(device_handle))
return CU_FALSE;

View File

@ -177,6 +177,7 @@ static uint32_t *ib_checksum;
static uint32_t *ib_size_in_dw;
static rvcn_decode_buffer_t *decode_buffer;
struct amdgpu_vcn_bo session_ctx_buf;
static amdgpu_bo_handle resources[MAX_RESOURCES];
static unsigned num_resources;
@ -561,7 +562,9 @@ static void amdgpu_cs_vcn_dec_create(void)
num_resources = 0;
alloc_resource(&msg_buf, 4096, AMDGPU_GEM_DOMAIN_GTT);
alloc_resource(&session_ctx_buf, 32 * 4096, AMDGPU_GEM_DOMAIN_VRAM);
resources[num_resources++] = msg_buf.handle;
resources[num_resources++] = session_ctx_buf.handle;
resources[num_resources++] = ib_handle;
r = amdgpu_bo_cpu_map(msg_buf.handle, (void **)&msg_buf.ptr);
@ -571,9 +574,11 @@ static void amdgpu_cs_vcn_dec_create(void)
memcpy(msg_buf.ptr, vcn_dec_create_msg, sizeof(vcn_dec_create_msg));
len = 0;
if (vcn_dec_sw_ring == true)
vcn_dec_cmd(session_ctx_buf.addr, 5, &len);
if (vcn_dec_sw_ring == true) {
vcn_dec_cmd(msg_buf.addr, 0, &len);
else {
} else {
ib_cpu[len++] = reg[vcn_reg_index].data0;
ib_cpu[len++] = msg_buf.addr;
ib_cpu[len++] = reg[vcn_reg_index].data1;
@ -650,6 +655,7 @@ static void amdgpu_cs_vcn_dec_decode(void)
dt_addr = ALIGN(dpb_addr + dpb_size, 4*1024);
len = 0;
vcn_dec_cmd(session_ctx_buf.addr, 0x5, &len);
vcn_dec_cmd(msg_addr, 0x0, &len);
vcn_dec_cmd(dpb_addr, 0x1, &len);
vcn_dec_cmd(dt_addr, 0x2, &len);
@ -702,9 +708,10 @@ static void amdgpu_cs_vcn_dec_destroy(void)
memcpy(msg_buf.ptr, vcn_dec_destroy_msg, sizeof(vcn_dec_destroy_msg));
len = 0;
if (vcn_dec_sw_ring == true)
vcn_dec_cmd(session_ctx_buf.addr, 5, &len);
if (vcn_dec_sw_ring == true) {
vcn_dec_cmd(msg_buf.addr, 0, &len);
else {
} else {
ib_cpu[len++] = reg[vcn_reg_index].data0;
ib_cpu[len++] = msg_buf.addr;
ib_cpu[len++] = reg[vcn_reg_index].data1;
@ -727,6 +734,7 @@ static void amdgpu_cs_vcn_dec_destroy(void)
CU_ASSERT_EQUAL(r, 0);
free_resource(&msg_buf);
free_resource(&session_ctx_buf);
}
static void amdgpu_cs_vcn_enc_create(void)
@ -808,6 +816,8 @@ static void amdgpu_cs_vcn_enc_create(void)
ib_cpu[len++] = 0;
ib_cpu[len++] = 0; /* pre encode mode */
ib_cpu[len++] = 0; /* chroma enabled : false */
ib_cpu[len++] = 0;
ib_cpu[len++] = 0;
*st_size = (len - st_offset) * 4;
/* slice control */
@ -829,7 +839,7 @@ static void amdgpu_cs_vcn_enc_create(void)
ib_cpu[len++] = 1; /* quarter pel enabled */
ib_cpu[len++] = 100; /* BASELINE profile */
ib_cpu[len++] = 11; /* level */
if (vcn_ip_version_major == 3) {
if (vcn_ip_version_major >= 3) {
ib_cpu[len++] = 0; /* b_picture_enabled */
ib_cpu[len++] = 0; /* weighted_bipred_idc */
}
@ -870,7 +880,7 @@ static void amdgpu_cs_vcn_enc_create(void)
ib_cpu[len++] = 0; /* scene change sensitivity */
ib_cpu[len++] = 0; /* scene change min idr interval */
ib_cpu[len++] = 0;
if (vcn_ip_version_major == 3)
if (vcn_ip_version_major >= 3)
ib_cpu[len++] = 0;
*st_size = (len - st_offset) * 4;
@ -913,6 +923,7 @@ static void amdgpu_cs_vcn_enc_create(void)
ib_cpu[len++] = 1;
ib_cpu[len++] = 0;
ib_cpu[len++] = 1;
ib_cpu[len++] = 0;
*st_size = (len - st_offset) * 4;
/* op init rc */
@ -1265,10 +1276,16 @@ static void check_result(struct amdgpu_vcn_bo fb_buf, struct amdgpu_vcn_bo bs_bu
CU_ASSERT_EQUAL(r, 0);
}
static void amdgpu_cs_vcn_ib_zero_count(int *len, int num)
{
for (int i = 0; i < num; i++)
ib_cpu[(*len)++] = 0;
}
static void amdgpu_cs_vcn_enc_encode_frame(int frame_type)
{
struct amdgpu_vcn_bo bs_buf, fb_buf, vbv_buf;
int len, r, i;
struct amdgpu_vcn_bo bs_buf, fb_buf, input_buf;
int len, r;
unsigned width = 160, height = 128, buf_size;
uint32_t *p_task_size = NULL;
uint32_t task_offset = 0, st_offset;
@ -1288,12 +1305,12 @@ static void amdgpu_cs_vcn_enc_encode_frame(int frame_type)
num_resources = 0;
alloc_resource(&bs_buf, 4096, AMDGPU_GEM_DOMAIN_GTT);
alloc_resource(&fb_buf, 4096, AMDGPU_GEM_DOMAIN_GTT);
alloc_resource(&vbv_buf, buf_size, AMDGPU_GEM_DOMAIN_GTT);
alloc_resource(&input_buf, buf_size, AMDGPU_GEM_DOMAIN_GTT);
resources[num_resources++] = enc_buf.handle;
resources[num_resources++] = cpb_buf.handle;
resources[num_resources++] = bs_buf.handle;
resources[num_resources++] = fb_buf.handle;
resources[num_resources++] = vbv_buf.handle;
resources[num_resources++] = input_buf.handle;
resources[num_resources++] = ib_handle;
@ -1305,13 +1322,13 @@ static void amdgpu_cs_vcn_enc_encode_frame(int frame_type)
memset(fb_buf.ptr, 0, 4096);
r = amdgpu_bo_cpu_unmap(fb_buf.handle);
r = amdgpu_bo_cpu_map(vbv_buf.handle, (void **)&vbv_buf.ptr);
r = amdgpu_bo_cpu_map(input_buf.handle, (void **)&input_buf.ptr);
CU_ASSERT_EQUAL(r, 0);
for (int i = 0; i < ALIGN(height, 32) * 3 / 2; i++)
memcpy(vbv_buf.ptr + i * ALIGN(width, 256), frame + i * width, width);
memcpy(input_buf.ptr + i * ALIGN(width, 256), frame + i * width, width);
r = amdgpu_bo_cpu_unmap(vbv_buf.handle);
r = amdgpu_bo_cpu_unmap(input_buf.handle);
CU_ASSERT_EQUAL(r, 0);
len = 0;
@ -1346,7 +1363,7 @@ static void amdgpu_cs_vcn_enc_encode_frame(int frame_type)
if(vcn_ip_version_major == 1)
ib_cpu[len++] = 0x00000020; /* RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU vcn 1 */
else
ib_cpu[len++] = 0x0000000a; /* RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU vcn 2,3 */
ib_cpu[len++] = 0x0000000a; /* RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU other vcn */
ib_cpu[len++] = 0x00000002; /* RENCODE_DIRECT_OUTPUT_NALU_TYPE_SPS */
ib_cpu[len++] = 0x00000011; /* sps len */
ib_cpu[len++] = 0x00000001; /* start code */
@ -1362,7 +1379,7 @@ static void amdgpu_cs_vcn_enc_encode_frame(int frame_type)
if(vcn_ip_version_major == 1)
ib_cpu[len++] = 0x00000020; /* RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU vcn 1*/
else
ib_cpu[len++] = 0x0000000a; /* RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU vcn 2,3*/
ib_cpu[len++] = 0x0000000a; /* RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU other vcn*/
ib_cpu[len++] = 0x00000003; /* RENCODE_DIRECT_OUTPUT_NALU_TYPE_PPS */
ib_cpu[len++] = 0x00000008; /* pps len */
ib_cpu[len++] = 0x00000001; /* start code */
@ -1376,7 +1393,7 @@ static void amdgpu_cs_vcn_enc_encode_frame(int frame_type)
if(vcn_ip_version_major == 1)
ib_cpu[len++] = 0x0000000a; /* RENCODE_IB_PARAM_SLICE_HEADER vcn 1 */
else
ib_cpu[len++] = 0x0000000b; /* RENCODE_IB_PARAM_SLICE_HEADER vcn 2,3 */
ib_cpu[len++] = 0x0000000b; /* RENCODE_IB_PARAM_SLICE_HEADER other vcn */
if (frame_type == 2) {
ib_cpu[len++] = 0x65000000;
ib_cpu[len++] = 0x11040000;
@ -1385,8 +1402,7 @@ static void amdgpu_cs_vcn_enc_encode_frame(int frame_type)
ib_cpu[len++] = 0x34210000;
}
ib_cpu[len++] = 0xe0000000;
for(i = 0; i < 13; i++)
ib_cpu[len++] = 0x00000000;
amdgpu_cs_vcn_ib_zero_count(&len, 13);
ib_cpu[len++] = 0x00000001;
ib_cpu[len++] = 0x00000008;
@ -1398,24 +1414,22 @@ static void amdgpu_cs_vcn_enc_encode_frame(int frame_type)
ib_cpu[len++] = 0x00000000;
ib_cpu[len++] = 0x00000001;
ib_cpu[len++] = 0x00000003;
for(i = 0; i < 22; i++)
ib_cpu[len++] = 0x00000000;
amdgpu_cs_vcn_ib_zero_count(&len, 22);
*st_size = (len - st_offset) * 4;
/* encode params */
st_offset = len;
st_size = &ib_cpu[len++]; /* size */
if(vcn_ip_version_major == 1)
ib_cpu[len++] = 0x0000000b; /* RENCODE_IB_PARAM_ENCODE_PARAMS vcn 1*/
ib_cpu[len++] = 0x0000000b; /* RENCODE_IB_PARAM_ENCODE_PARAMS vcn 1 */
else
ib_cpu[len++] = 0x0000000f; /* RENCODE_IB_PARAM_ENCODE_PARAMS vcn 2,3*/
ib_cpu[len++] = 0x0000000f; /* RENCODE_IB_PARAM_ENCODE_PARAMS other vcn */
ib_cpu[len++] = frame_type;
ib_cpu[len++] = 0x0001f000;
ib_cpu[len++] = vbv_buf.addr >> 32;
ib_cpu[len++] = vbv_buf.addr;
ib_cpu[len++] = (vbv_buf.addr + ALIGN(width, 256) * ALIGN(height, 32)) >> 32;
ib_cpu[len++] = vbv_buf.addr + ALIGN(width, 256) * ALIGN(height, 32);
ib_cpu[len++] = input_buf.addr >> 32;
ib_cpu[len++] = input_buf.addr;
ib_cpu[len++] = (input_buf.addr + ALIGN(width, 256) * ALIGN(height, 32)) >> 32;
ib_cpu[len++] = input_buf.addr + ALIGN(width, 256) * ALIGN(height, 32);
ib_cpu[len++] = 0x00000100;
ib_cpu[len++] = 0x00000080;
ib_cpu[len++] = 0x00000000;
@ -1427,7 +1441,7 @@ static void amdgpu_cs_vcn_enc_encode_frame(int frame_type)
st_offset = len;
st_size = &ib_cpu[len++]; /* size */
ib_cpu[len++] = 0x00200003; /* RENCODE_H264_IB_PARAM_ENCODE_PARAMS */
if (vcn_ip_version_major != 3) {
if (vcn_ip_version_major <= 2) {
ib_cpu[len++] = 0x00000000;
ib_cpu[len++] = 0x00000000;
ib_cpu[len++] = 0x00000000;
@ -1450,6 +1464,7 @@ static void amdgpu_cs_vcn_enc_encode_frame(int frame_type)
ib_cpu[len++] = 0x00000000;
ib_cpu[len++] = 0x00000000;
ib_cpu[len++] = 0x00000000;
ib_cpu[len++] = 0x00000001;
}
*st_size = (len - st_offset) * 4;
@ -1459,20 +1474,21 @@ static void amdgpu_cs_vcn_enc_encode_frame(int frame_type)
if(vcn_ip_version_major == 1)
ib_cpu[len++] = 0x0000000d; /* ENCODE_CONTEXT_BUFFER vcn 1 */
else
ib_cpu[len++] = 0x00000011; /* ENCODE_CONTEXT_BUFFER vcn 2,3 */
ib_cpu[len++] = 0x00000011; /* ENCODE_CONTEXT_BUFFER other vcn */
ib_cpu[len++] = cpb_buf.addr >> 32;
ib_cpu[len++] = cpb_buf.addr;
ib_cpu[len++] = 0x00000000; /* swizzle mode */
ib_cpu[len++] = 0x00000100; /* luma pitch */
ib_cpu[len++] = 0x00000100; /* chroma pitch */
ib_cpu[len++] = 0x00000003; /* no reconstructed picture */
ib_cpu[len++] = 0x00000002; /* no reconstructed picture */
ib_cpu[len++] = 0x00000000; /* reconstructed pic 1 luma offset */
ib_cpu[len++] = ALIGN(width, 256) * ALIGN(height, 32); /* pic1 chroma offset */
if(vcn_ip_version_major == 4)
amdgpu_cs_vcn_ib_zero_count(&len, 2);
ib_cpu[len++] = ALIGN(width, 256) * ALIGN(height, 32) * 3 / 2; /* pic2 luma offset */
ib_cpu[len++] = ALIGN(width, 256) * ALIGN(height, 32) * 5 / 2; /* pic2 chroma offset */
for (int i = 0; i < 136; i++)
ib_cpu[len++] = 0x00000000;
amdgpu_cs_vcn_ib_zero_count(&len, 280);
*st_size = (len - st_offset) * 4;
/* bitstream buffer */
@ -1481,7 +1497,8 @@ static void amdgpu_cs_vcn_enc_encode_frame(int frame_type)
if(vcn_ip_version_major == 1)
ib_cpu[len++] = 0x0000000e; /* VIDEO_BITSTREAM_BUFFER vcn 1 */
else
ib_cpu[len++] = 0x00000012; /* VIDEO_BITSTREAM_BUFFER vcn 2,3 */
ib_cpu[len++] = 0x00000012; /* VIDEO_BITSTREAM_BUFFER other vcn */
ib_cpu[len++] = 0x00000000; /* mode */
ib_cpu[len++] = bs_buf.addr >> 32;
ib_cpu[len++] = bs_buf.addr;
@ -1564,7 +1581,7 @@ static void amdgpu_cs_vcn_enc_encode_frame(int frame_type)
free_resource(&fb_buf);
free_resource(&bs_buf);
free_resource(&vbv_buf);
free_resource(&input_buf);
}
static void amdgpu_cs_vcn_enc_encode(void)

View File

@ -124,16 +124,36 @@ bo_create(int fd, unsigned int format,
int ret;
switch (format) {
case DRM_FORMAT_C1:
bpp = 1;
break;
case DRM_FORMAT_C2:
bpp = 2;
break;
case DRM_FORMAT_C4:
bpp = 4;
break;
case DRM_FORMAT_C8:
case DRM_FORMAT_NV12:
case DRM_FORMAT_NV21:
case DRM_FORMAT_NV16:
case DRM_FORMAT_NV61:
case DRM_FORMAT_NV24:
case DRM_FORMAT_NV42:
case DRM_FORMAT_YUV420:
case DRM_FORMAT_YVU420:
bpp = 8;
break;
case DRM_FORMAT_NV15:
case DRM_FORMAT_NV20:
case DRM_FORMAT_NV30:
bpp = 10;
break;
case DRM_FORMAT_ARGB4444:
case DRM_FORMAT_XRGB4444:
case DRM_FORMAT_ABGR4444:
@ -144,6 +164,7 @@ bo_create(int fd, unsigned int format,
case DRM_FORMAT_BGRX4444:
case DRM_FORMAT_ARGB1555:
case DRM_FORMAT_XRGB1555:
case DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN:
case DRM_FORMAT_ABGR1555:
case DRM_FORMAT_XBGR1555:
case DRM_FORMAT_RGBA5551:
@ -151,6 +172,7 @@ bo_create(int fd, unsigned int format,
case DRM_FORMAT_BGRA5551:
case DRM_FORMAT_BGRX5551:
case DRM_FORMAT_RGB565:
case DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN:
case DRM_FORMAT_BGR565:
case DRM_FORMAT_UYVY:
case DRM_FORMAT_VYUY:
@ -198,6 +220,7 @@ bo_create(int fd, unsigned int format,
switch (format) {
case DRM_FORMAT_NV12:
case DRM_FORMAT_NV21:
case DRM_FORMAT_NV15:
case DRM_FORMAT_YUV420:
case DRM_FORMAT_YVU420:
virtual_height = height * 3 / 2;
@ -205,9 +228,16 @@ bo_create(int fd, unsigned int format,
case DRM_FORMAT_NV16:
case DRM_FORMAT_NV61:
case DRM_FORMAT_NV20:
virtual_height = height * 2;
break;
case DRM_FORMAT_NV24:
case DRM_FORMAT_NV42:
case DRM_FORMAT_NV30:
virtual_height = height * 3;
break;
default:
virtual_height = height;
break;
@ -244,6 +274,8 @@ bo_create(int fd, unsigned int format,
case DRM_FORMAT_NV21:
case DRM_FORMAT_NV16:
case DRM_FORMAT_NV61:
case DRM_FORMAT_NV15:
case DRM_FORMAT_NV20:
offsets[0] = 0;
handles[0] = bo->handle;
pitches[0] = bo->pitch;
@ -255,6 +287,20 @@ bo_create(int fd, unsigned int format,
planes[1] = virtual + offsets[1];
break;
case DRM_FORMAT_NV24:
case DRM_FORMAT_NV42:
case DRM_FORMAT_NV30:
offsets[0] = 0;
handles[0] = bo->handle;
pitches[0] = bo->pitch;
pitches[1] = pitches[0] * 2;
offsets[1] = pitches[0] * height;
handles[1] = bo->handle;
planes[0] = virtual;
planes[1] = virtual + offsets[1];
break;
case DRM_FORMAT_YUV420:
case DRM_FORMAT_YVU420:
offsets[0] = 0;
@ -272,6 +318,9 @@ bo_create(int fd, unsigned int format,
planes[2] = virtual + offsets[2];
break;
case DRM_FORMAT_C1:
case DRM_FORMAT_C2:
case DRM_FORMAT_C4:
case DRM_FORMAT_C8:
case DRM_FORMAT_ARGB4444:
case DRM_FORMAT_XRGB4444:
@ -283,6 +332,7 @@ bo_create(int fd, unsigned int format,
case DRM_FORMAT_BGRX4444:
case DRM_FORMAT_ARGB1555:
case DRM_FORMAT_XRGB1555:
case DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN:
case DRM_FORMAT_ABGR1555:
case DRM_FORMAT_XBGR1555:
case DRM_FORMAT_RGBA5551:
@ -290,6 +340,7 @@ bo_create(int fd, unsigned int format,
case DRM_FORMAT_BGRA5551:
case DRM_FORMAT_BGRX5551:
case DRM_FORMAT_RGB565:
case DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN:
case DRM_FORMAT_BGR565:
case DRM_FORMAT_BGR888:
case DRM_FORMAT_RGB888:
@ -338,3 +389,22 @@ void bo_destroy(struct bo *bo)
free(bo);
}
void bo_dump(struct bo *bo, const char *filename)
{
FILE *fp;
if (!bo || !filename)
return;
fp = fopen(filename, "wb");
if (fp) {
void *addr;
bo_map(bo, &addr);
printf("Dumping buffer %p to file %s.\n", bo->ptr, filename);
fwrite(bo->ptr, 1, bo->size, fp);
bo_unmap(bo);
fclose(fp);
}
}

View File

@ -36,5 +36,6 @@ struct bo *bo_create(int fd, unsigned int format,
unsigned int handles[4], unsigned int pitches[4],
unsigned int offsets[4], enum util_fill_pattern pattern);
void bo_destroy(struct bo *bo);
void bo_dump(struct bo *bo, const char *filename);
#endif

View File

@ -25,5 +25,6 @@ modetest = executable(
include_directories : [inc_root, inc_tests, inc_drm],
dependencies : [dep_threads, dep_cairo],
link_with : [libdrm, libutil],
link_args: '-lm',
install : with_install_tests,
)

View File

@ -70,6 +70,7 @@
static enum util_fill_pattern primary_fill = UTIL_PATTERN_SMPTE;
static enum util_fill_pattern secondary_fill = UTIL_PATTERN_TILES;
static drmModeModeInfo user_mode;
struct crtc {
drmModeCrtc *crtc;
@ -128,6 +129,7 @@ struct device {
int use_atomic;
drmModeAtomicReq *req;
int32_t writeback_fence_fd;
};
static inline int64_t U642I64(uint64_t val)
@ -137,8 +139,19 @@ static inline int64_t U642I64(uint64_t val)
static float mode_vrefresh(drmModeModeInfo *mode)
{
return mode->clock * 1000.00
/ (mode->htotal * mode->vtotal);
unsigned int num, den;
num = mode->clock;
den = mode->htotal * mode->vtotal;
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
num *= 2;
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
den *= 2;
if (mode->vscan > 1)
den *= mode->vscan;
return num * 1000.00 / den;
}
#define bit_name_fn(res) \
@ -317,7 +330,7 @@ static void dump_in_formats(struct device *dev, uint32_t blob_id)
printf(": ");
}
printf(" %s", modifier_to_string(iter.mod));
printf(" %s(0x%"PRIx64")", modifier_to_string(iter.mod), iter.mod);
}
printf("\n");
@ -804,13 +817,15 @@ struct pipe_arg {
unsigned int num_cons;
uint32_t crtc_id;
char mode_str[64];
char format_str[5];
char format_str[8]; /* need to leave room for "_BE" and terminating \0 */
float vrefresh;
unsigned int fourcc;
drmModeModeInfo *mode;
struct crtc *crtc;
unsigned int fb_id[2], current_fb_id;
struct timeval start;
unsigned int out_fb_id;
struct bo *out_bo;
int swap_count;
};
@ -826,7 +841,7 @@ struct plane_arg {
unsigned int old_fb_id;
struct bo *bo;
struct bo *old_bo;
char format_str[5]; /* need to leave room for terminating \0 */
char format_str[8]; /* need to leave room for "_BE" and terminating \0 */
unsigned int fourcc;
};
@ -839,7 +854,25 @@ connector_find_mode(struct device *dev, uint32_t con_id, const char *mode_str,
int i;
connector = get_connector_by_id(dev, con_id);
if (!connector || !connector->count_modes)
if (!connector)
return NULL;
if (strchr(mode_str, ',')) {
i = sscanf(mode_str, "%hu,%hu,%hu,%hu,%hu,%hu,%hu,%hu",
&user_mode.hdisplay, &user_mode.hsync_start,
&user_mode.hsync_end, &user_mode.htotal,
&user_mode.vdisplay, &user_mode.vsync_start,
&user_mode.vsync_end, &user_mode.vtotal);
if (i == 8) {
user_mode.clock = roundf(user_mode.htotal * user_mode.vtotal * vrefresh / 1000);
user_mode.vrefresh = roundf(vrefresh);
snprintf(user_mode.name, sizeof(user_mode.name), "custom%dx%d", user_mode.hdisplay, user_mode.vdisplay);
return &user_mode;
}
}
if (!connector->count_modes)
return NULL;
/* Pick by Index */
@ -1040,7 +1073,7 @@ static bool set_property(struct device *dev, struct property_arg *p)
if (ret < 0)
fprintf(stderr, "failed to set %s %i property %s to %" PRIu64 ": %s\n",
obj_type, p->obj_id, p->name, p->value, strerror(errno));
obj_type, p->obj_id, p->name, p->value, strerror(-ret));
return true;
}
@ -1116,15 +1149,23 @@ static bool add_property_optional(struct device *dev, uint32_t obj_id,
static void set_gamma(struct device *dev, unsigned crtc_id, unsigned fourcc)
{
unsigned blob_id = 0;
const struct util_format_info *info;
/* TODO: support 1024-sized LUTs, when the use-case arises */
struct drm_color_lut gamma_lut[256];
int i, ret;
if (fourcc == DRM_FORMAT_C8) {
/* TODO: Add C8 support for more patterns */
util_smpte_c8_gamma(256, gamma_lut);
info = util_format_info_find(fourcc);
if (info->ncolors) {
memset(gamma_lut, 0, sizeof(gamma_lut));
/* TODO: Add index support for more patterns */
util_smpte_fill_lut(info->ncolors, gamma_lut);
drmModeCreatePropertyBlob(dev->fd, gamma_lut, sizeof(gamma_lut), &blob_id);
} else {
/*
* Initialize gamma_lut to a linear table for the legacy API below.
* The modern property API resets to a linear/pass-thru table if blob_id
* is 0, hence no PropertyBlob is created here.
*/
for (i = 0; i < 256; i++) {
gamma_lut[i].red =
gamma_lut[i].green =
@ -1135,6 +1176,7 @@ static void set_gamma(struct device *dev, unsigned crtc_id, unsigned fourcc)
add_property_optional(dev, crtc_id, "DEGAMMA_LUT", 0);
add_property_optional(dev, crtc_id, "CTM", 0);
if (!add_property_optional(dev, crtc_id, "GAMMA_LUT", blob_id)) {
/* If we can't add the GAMMA_LUT property, try the legacy API. */
uint16_t r[256], g[256], b[256];
for (i = 0; i < 256; i++) {
@ -1144,7 +1186,7 @@ static void set_gamma(struct device *dev, unsigned crtc_id, unsigned fourcc)
}
ret = drmModeCrtcSetGamma(dev->fd, crtc_id, 256, r, g, b);
if (ret)
if (ret && errno != ENOSYS)
fprintf(stderr, "failed to set gamma: %s\n", strerror(errno));
}
}
@ -1441,6 +1483,24 @@ static int pipe_resolve_connectors(struct device *dev, struct pipe_arg *pipe)
return 0;
}
static bool pipe_has_writeback_connector(struct device *dev, struct pipe_arg *pipes,
unsigned int count)
{
drmModeConnector *connector;
unsigned int i, j;
for (j = 0; j < count; j++) {
struct pipe_arg *pipe = &pipes[j];
for (i = 0; i < pipe->num_cons; i++) {
connector = get_connector_by_id(dev, pipe->con_ids[i]);
if (connector && connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
return true;
}
}
return false;
}
static int pipe_attempt_connector(struct device *dev, drmModeConnector *con,
struct pipe_arg *pipe)
{
@ -1503,7 +1563,8 @@ static int pipe_find_preferred(struct device *dev, struct pipe_arg **out_pipes)
for (i = 0; i < res->count_connectors; i++) {
con = res->connectors[i].connector;
if (!con || con->connection != DRM_MODE_CONNECTED)
if (!con || con->connection != DRM_MODE_CONNECTED ||
con->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
continue;
connected++;
}
@ -1550,32 +1611,35 @@ static struct plane *get_primary_plane_by_crtc(struct device *dev, struct crtc *
return NULL;
}
static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count)
static unsigned int set_mode(struct device *dev, struct pipe_arg **pipe_args, unsigned int count)
{
unsigned int i, j;
int ret, x = 0;
int preferred = count == 0;
struct pipe_arg *pipes;
for (i = 0; i < count; i++) {
struct pipe_arg *pipe = &pipes[i];
ret = pipe_resolve_connectors(dev, pipe);
if (ret < 0)
return;
ret = pipe_find_crtc_and_mode(dev, pipe);
if (ret < 0)
continue;
}
if (preferred) {
struct pipe_arg *pipe_args;
count = pipe_find_preferred(dev, &pipe_args);
count = pipe_find_preferred(dev, pipe_args);
if (!count) {
fprintf(stderr, "can't find any preferred connector/mode.\n");
return;
return 0;
}
pipes = *pipe_args;
} else {
pipes = *pipe_args;
for (i = 0; i < count; i++) {
struct pipe_arg *pipe = &pipes[i];
ret = pipe_resolve_connectors(dev, pipe);
if (ret < 0)
return 0;
ret = pipe_find_crtc_and_mode(dev, pipe);
if (ret < 0)
continue;
}
pipes = pipe_args;
}
if (!dev->use_atomic) {
@ -1602,7 +1666,7 @@ static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int co
if (bo_fb_create(dev->fd, pipes[0].fourcc, dev->mode.width, dev->mode.height,
primary_fill, &dev->mode.bo, &dev->mode.fb_id))
return;
return 0;
}
for (i = 0; i < count; i++) {
@ -1634,7 +1698,7 @@ static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int co
if (ret) {
fprintf(stderr, "failed to set mode: %s\n", strerror(errno));
return;
return 0;
}
set_gamma(dev, pipe->crtc_id, pipe->fourcc);
@ -1660,6 +1724,77 @@ static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int co
}
}
}
return count;
}
static void writeback_config(struct device *dev, struct pipe_arg *pipes, unsigned int count)
{
drmModeConnector *connector;
unsigned int i, j;
for (j = 0; j < count; j++) {
struct pipe_arg *pipe = &pipes[j];
for (i = 0; i < pipe->num_cons; i++) {
connector = get_connector_by_id(dev, pipe->con_ids[i]);
if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) {
if (!pipe->mode) {
fprintf(stderr, "no mode for writeback\n");
return;
}
bo_fb_create(dev->fd, pipes[j].fourcc,
pipe->mode->hdisplay, pipe->mode->vdisplay,
UTIL_PATTERN_PLAIN,
&pipe->out_bo, &pipe->out_fb_id);
add_property(dev, pipe->con_ids[i], "WRITEBACK_FB_ID",
pipe->out_fb_id);
add_property(dev, pipe->con_ids[i], "WRITEBACK_OUT_FENCE_PTR",
(uintptr_t)(&dev->writeback_fence_fd));
}
}
}
}
static int poll_writeback_fence(int fd, int timeout)
{
struct pollfd fds = { fd, POLLIN };
int ret;
do {
ret = poll(&fds, 1, timeout);
if (ret > 0) {
if (fds.revents & (POLLERR | POLLNVAL))
return -EINVAL;
return 0;
} else if (ret == 0) {
return -ETIMEDOUT;
} else {
ret = -errno;
if (ret == -EINTR || ret == -EAGAIN)
continue;
return ret;
}
} while (1);
}
static void dump_output_fb(struct device *dev, struct pipe_arg *pipes, char *dump_path,
unsigned int count)
{
drmModeConnector *connector;
unsigned int i, j;
for (j = 0; j < count; j++) {
struct pipe_arg *pipe = &pipes[j];
for (i = 0; i < pipe->num_cons; i++) {
connector = get_connector_by_id(dev, pipe->con_ids[i]);
if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
bo_dump(pipe->out_bo, dump_path);
}
}
}
static void atomic_clear_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count)
@ -1897,8 +2032,9 @@ static int parse_connector(struct pipe_arg *pipe, const char *arg)
}
if (*p == '@') {
strncpy(pipe->format_str, p + 1, 4);
pipe->format_str[4] = '\0';
len = sizeof(pipe->format_str) - 1;
strncpy(pipe->format_str, p + 1, len);
pipe->format_str[len] = '\0';
}
pipe->fourcc = util_format_fourcc(pipe->format_str);
@ -1912,6 +2048,7 @@ static int parse_connector(struct pipe_arg *pipe, const char *arg)
static int parse_plane(struct plane_arg *plane, const char *p)
{
unsigned int len;
char *end;
plane->plane_id = strtoul(p, &end, 10);
@ -1950,8 +2087,9 @@ static int parse_plane(struct plane_arg *plane, const char *p)
}
if (*end == '@') {
strncpy(plane->format_str, end + 1, 4);
plane->format_str[4] = '\0';
len = sizeof(plane->format_str) - 1;
strncpy(plane->format_str, end + 1, len);
plane->format_str[len] = '\0';
} else {
strcpy(plane->format_str, "XR24");
}
@ -1990,7 +2128,7 @@ static void parse_fill_patterns(char *arg)
static void usage(char *name)
{
fprintf(stderr, "usage: %s [-acDdefMPpsCvrw]\n", name);
fprintf(stderr, "usage: %s [-acDdefMoPpsCvrw]\n", name);
fprintf(stderr, "\n Query options:\n\n");
fprintf(stderr, "\t-c\tlist connectors\n");
@ -1999,14 +2137,19 @@ static void usage(char *name)
fprintf(stderr, "\t-p\tlist CRTCs and planes (pipes)\n");
fprintf(stderr, "\n Test options:\n\n");
fprintf(stderr, "\t-P <plane_id>@<crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>]\tset a plane\n");
fprintf(stderr, "\t-s <connector_id>[,<connector_id>][@<crtc_id>]:[#<mode index>]<mode>[-<vrefresh>][@<format>]\tset a mode\n");
fprintf(stderr, "\t-P <plane_id>@<crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>]\tset a plane, see 'plane-topology'\n");
fprintf(stderr, "\t-s <connector_id>[,<connector_id>][@<crtc_id>]:mode[@<format>]\tset a mode, see 'mode-topology'\n");
fprintf(stderr, "\t\twhere mode can be specified as:\n");
fprintf(stderr, "\t\t<hdisp>x<vdisp>[-<vrefresh>]\n");
fprintf(stderr, "\t\t<hdisp>,<hss>,<hse>,<htot>,<vdisp>,<vss>,<vse>,<vtot>-<vrefresh>\n");
fprintf(stderr, "\t\t#<mode index>\n");
fprintf(stderr, "\t-C\ttest hw cursor\n");
fprintf(stderr, "\t-v\ttest vsynced page flipping\n");
fprintf(stderr, "\t-r\tset the preferred mode for all connectors\n");
fprintf(stderr, "\t-w <obj_id>:<prop_name>:<value>\tset property\n");
fprintf(stderr, "\t-w <obj_id>:<prop_name>:<value>\tset property, see 'property'\n");
fprintf(stderr, "\t-a \tuse atomic API\n");
fprintf(stderr, "\t-F pattern1,pattern2\tspecify fill patterns\n");
fprintf(stderr, "\t-o <desired file path> \t Dump writeback output buffer to file\n");
fprintf(stderr, "\n Generic options:\n\n");
fprintf(stderr, "\t-d\tdrop master after mode set\n");
@ -2014,10 +2157,29 @@ static void usage(char *name)
fprintf(stderr, "\t-D device\tuse the given device\n");
fprintf(stderr, "\n\tDefault is to dump all info.\n");
fprintf(stderr, "\n");
fprintf(stderr, "Plane Topology is defined as:\n");
fprintf(stderr, "\tplane-topology\t::= plane-id '@' crtc-id ':' width 'x' height ( <plane-offsets> )? ;\n");
fprintf(stderr, "\tplane-offsets\t::= '+' x-offset '+' y-offset ( <plane-scale> )? ;\n");
fprintf(stderr, "\tplane-scale\t::= '*' scale ( <plane-format> )? ;\n");
fprintf(stderr, "\tplane-format\t::= '@' format ;\n");
fprintf(stderr, "\n");
fprintf(stderr, "Mode Topology is defined as:\n");
fprintf(stderr, "\tmode-topology\t::= connector-id ( ',' connector-id )* ( '@' crtc-id )? ':' <mode-selection> ( '@' format )? ;\n");
fprintf(stderr, "\tmode-selection\t::= <indexed-mode> | <named-mode> | <custom-mode> ;\n");
fprintf(stderr, "\tindexed-mode\t::= '#' mode-index ;\n");
fprintf(stderr, "\tnamed-mode\t::= width 'x' height ( '-' vrefresh )? ;\n");
fprintf(stderr, "\tcustom-mode\t::= hdisplay ',' hsyncstart ',' hsyncend ',' htotal ',' vdisplay ',' vsyncstart ',' vsyncend ',' vtotal '-' vrefresh ;\n");
fprintf(stderr, "\n");
fprintf(stderr, "Property is defined as:\n");
fprintf(stderr, "\tproperty\t::= object-id ':' property-name ':' value ;\n");
exit(0);
}
static char optstr[] = "acdD:efF:M:P:ps:Cvrw:";
static char optstr[] = "acdD:efF:M:P:ps:Cvrw:o:";
int main(int argc, char **argv)
{
@ -2040,6 +2202,7 @@ int main(int argc, char **argv)
struct property_arg *prop_args = NULL;
unsigned int args = 0;
int ret;
char *dump_path = NULL;
memset(&dev, 0, sizeof dev);
@ -2078,6 +2241,9 @@ int main(int argc, char **argv)
/* Preserve the default behaviour of dumping all information. */
args--;
break;
case 'o':
dump_path = optarg;
break;
case 'P':
plane_args = realloc(plane_args,
(plane_count + 1) * sizeof *plane_args);
@ -2143,8 +2309,8 @@ int main(int argc, char **argv)
if (!args)
encoders = connectors = crtcs = planes = framebuffers = 1;
if (test_vsync && !count) {
fprintf(stderr, "page flipping requires at least one -s option.\n");
if (test_vsync && !count && !set_preferred) {
fprintf(stderr, "page flipping requires at least one -s or -r option.\n");
return -1;
}
if (set_preferred && count) {
@ -2152,17 +2318,13 @@ int main(int argc, char **argv)
return -1;
}
if (set_preferred && plane_count) {
fprintf(stderr, "cannot use -r (preferred) when -P (plane) is set\n");
return -1;
}
dev.fd = util_open(device, module);
if (dev.fd < 0)
return -1;
if (use_atomic) {
ret = drmSetClientCap(dev.fd, DRM_CLIENT_CAP_ATOMIC, 1);
drmSetClientCap(dev.fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
if (ret) {
fprintf(stderr, "no atomic modesetting support: %s\n", strerror(errno));
drmClose(dev.fd);
@ -2186,12 +2348,13 @@ int main(int argc, char **argv)
dump_resource(&dev, planes);
dump_resource(&dev, framebuffers);
if (dev.use_atomic)
dev.req = drmModeAtomicAlloc();
for (i = 0; i < prop_count; ++i)
set_property(&dev, &prop_args[i]);
if (dev.use_atomic) {
dev.req = drmModeAtomicAlloc();
if (set_preferred || (count && plane_count)) {
uint64_t cap = 0;
@ -2202,7 +2365,16 @@ int main(int argc, char **argv)
}
if (set_preferred || count)
set_mode(&dev, pipe_args, count);
count = set_mode(&dev, &pipe_args, count);
if (dump_path) {
if (!pipe_has_writeback_connector(&dev, pipe_args, count)) {
fprintf(stderr, "No writeback connector found, can not dump.\n");
return 1;
}
writeback_config(&dev, pipe_args, count);
}
if (plane_count)
atomic_set_planes(&dev, plane_args, plane_count, false);
@ -2213,6 +2385,18 @@ int main(int argc, char **argv)
return 1;
}
/*
* Since only writeback connectors have an output fb, this should only be
* called for writeback.
*/
if (dump_path) {
ret = poll_writeback_fence(dev.writeback_fence_fd, 1000);
if (ret)
fprintf(stderr, "Poll for writeback error: %d. Skipping Dump.\n",
ret);
dump_output_fb(&dev, pipe_args, dump_path, count);
}
if (test_vsync)
atomic_test_page_flip(&dev, pipe_args, plane_args, plane_count);
@ -2230,17 +2414,22 @@ int main(int argc, char **argv)
if (count)
atomic_clear_mode(&dev, pipe_args, count);
ret = drmModeAtomicCommit(dev.fd, dev.req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
if (ret)
fprintf(stderr, "Atomic Commit failed\n");
if (plane_count)
atomic_clear_FB(&dev, plane_args, plane_count);
}
ret = drmModeAtomicCommit(dev.fd, dev.req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
if (ret)
fprintf(stderr, "Atomic Commit failed\n");
if (count && plane_count)
atomic_clear_FB(&dev, plane_args, plane_count);
drmModeAtomicFree(dev.req);
} else {
if (dump_path) {
fprintf(stderr, "writeback / dump is only supported in atomic mode\n");
return 1;
}
if (set_preferred || count || plane_count) {
uint64_t cap = 0;
@ -2251,7 +2440,7 @@ int main(int argc, char **argv)
}
if (set_preferred || count)
set_mode(&dev, pipe_args, count);
count = set_mode(&dev, &pipe_args, count);
if (plane_count)
set_planes(&dev, plane_args, plane_count);

View File

@ -40,7 +40,10 @@
static const struct util_format_info format_info[] = {
/* Indexed */
{ DRM_FORMAT_C8, "C8" },
{ DRM_FORMAT_C1, "C1", .ncolors = 2 },
{ DRM_FORMAT_C2, "C2", .ncolors = 4 },
{ DRM_FORMAT_C4, "C4", .ncolors = 16 },
{ DRM_FORMAT_C8, "C8", .ncolors = 256 },
/* YUV packed */
{ DRM_FORMAT_UYVY, "UYVY", MAKE_YUV_INFO(YUV_YCbCr | YUV_CY, 2, 2, 2) },
{ DRM_FORMAT_VYUY, "VYUY", MAKE_YUV_INFO(YUV_YCrCb | YUV_CY, 2, 2, 2) },
@ -51,6 +54,11 @@ static const struct util_format_info format_info[] = {
{ DRM_FORMAT_NV21, "NV21", MAKE_YUV_INFO(YUV_YCrCb, 2, 2, 2) },
{ DRM_FORMAT_NV16, "NV16", MAKE_YUV_INFO(YUV_YCbCr, 2, 1, 2) },
{ DRM_FORMAT_NV61, "NV61", MAKE_YUV_INFO(YUV_YCrCb, 2, 1, 2) },
{ DRM_FORMAT_NV24, "NV24", MAKE_YUV_INFO(YUV_YCbCr, 1, 1, 2) },
{ DRM_FORMAT_NV42, "NV42", MAKE_YUV_INFO(YUV_YCrCb, 1, 1, 2) },
{ DRM_FORMAT_NV15, "NV15", MAKE_YUV_INFO(YUV_YCbCr, 2, 2, 2) },
{ DRM_FORMAT_NV20, "NV20", MAKE_YUV_INFO(YUV_YCbCr, 2, 1, 2) },
{ DRM_FORMAT_NV30, "NV30", MAKE_YUV_INFO(YUV_YCbCr, 1, 1, 2) },
/* YUV planar */
{ DRM_FORMAT_YUV420, "YU12", MAKE_YUV_INFO(YUV_YCbCr, 2, 2, 1) },
{ DRM_FORMAT_YVU420, "YV12", MAKE_YUV_INFO(YUV_YCrCb, 2, 2, 1) },
@ -73,6 +81,9 @@ static const struct util_format_info format_info[] = {
{ DRM_FORMAT_BGRX5551, "BX15", MAKE_RGB_INFO(5, 1, 5, 6, 5, 11, 0, 0) },
{ DRM_FORMAT_RGB565, "RG16", MAKE_RGB_INFO(5, 11, 6, 5, 5, 0, 0, 0) },
{ DRM_FORMAT_BGR565, "BG16", MAKE_RGB_INFO(5, 0, 6, 5, 5, 11, 0, 0) },
/* Big-endian RGB16 */
{ DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN, "XR15_BE", MAKE_RGB_INFO(5, 10, 5, 5, 5, 0, 0, 0) },
{ DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN, "RG16_BE", MAKE_RGB_INFO(5, 11, 6, 5, 5, 0, 0, 0) },
/* RGB24 */
{ DRM_FORMAT_BGR888, "BG24", MAKE_RGB_INFO(8, 0, 8, 8, 8, 16, 0, 0) },
{ DRM_FORMAT_RGB888, "RG24", MAKE_RGB_INFO(8, 16, 8, 8, 8, 0, 0, 0) },

View File

@ -55,6 +55,7 @@ struct util_yuv_info {
struct util_format_info {
uint32_t format;
const char *name;
unsigned int ncolors;
const struct util_rgb_info rgb;
const struct util_yuv_info yuv;
};

View File

@ -125,6 +125,7 @@ static const char * const modules[] = {
"mxsfb-drm",
"simpledrm",
"imx-lcdif",
"vkms",
};
int util_open(const char *device, const char *module)

File diff suppressed because it is too large Load Diff

View File

@ -39,7 +39,7 @@ void util_fill_pattern(uint32_t format, enum util_fill_pattern pattern,
void *planes[3], unsigned int width,
unsigned int height, unsigned int stride);
void util_smpte_c8_gamma(unsigned size, struct drm_color_lut *lut);
void util_smpte_fill_lut(unsigned int ncolors, struct drm_color_lut *lut);
enum util_fill_pattern util_pattern_enum(const char *name);

View File

@ -833,8 +833,6 @@ static const char *drmGetDeviceName(int type)
switch (type) {
case DRM_NODE_PRIMARY:
return DRM_DEV_NAME;
case DRM_NODE_CONTROL:
return DRM_CONTROL_DEV_NAME;
case DRM_NODE_RENDER:
return DRM_RENDER_DEV_NAME;
}
@ -1053,8 +1051,6 @@ static int drmGetMinorBase(int type)
switch (type) {
case DRM_NODE_PRIMARY:
return 0;
case DRM_NODE_CONTROL:
return 64;
case DRM_NODE_RENDER:
return 128;
default:
@ -1075,8 +1071,6 @@ static int drmGetMinorType(int major, int minor)
// If not in /dev/drm/ we have the type in the name
if (sscanf(name, "dri/card%d\n", &id) >= 1)
return DRM_NODE_PRIMARY;
else if (sscanf(name, "dri/control%d\n", &id) >= 1)
return DRM_NODE_CONTROL;
else if (sscanf(name, "dri/renderD%d\n", &id) >= 1)
return DRM_NODE_RENDER;
return -1;
@ -1084,19 +1078,20 @@ static int drmGetMinorType(int major, int minor)
minor = id;
#endif
int type = minor >> 6;
char path[DRM_NODE_NAME_MAX];
const char *dev_name;
int i;
if (minor < 0)
return -1;
switch (type) {
case DRM_NODE_PRIMARY:
case DRM_NODE_CONTROL:
case DRM_NODE_RENDER:
return type;
default:
return -1;
for (i = DRM_NODE_PRIMARY; i < DRM_NODE_MAX; i++) {
dev_name = drmGetDeviceName(i);
if (!dev_name)
continue;
snprintf(path, sizeof(path), dev_name, DRM_DIR_NAME, minor);
if (!access(path, F_OK))
return i;
}
return -1;
}
static const char *drmGetMinorName(int type)
@ -1104,8 +1099,6 @@ static const char *drmGetMinorName(int type)
switch (type) {
case DRM_NODE_PRIMARY:
return DRM_PRIMARY_MINOR_NAME;
case DRM_NODE_CONTROL:
return DRM_CONTROL_MINOR_NAME;
case DRM_NODE_RENDER:
return DRM_RENDER_MINOR_NAME;
default:
@ -1292,7 +1285,7 @@ drm_public int drmOpen(const char *name, const char *busid)
*
* \param name driver name. Not referenced if bus ID is supplied.
* \param busid bus ID. Zero if not known.
* \param type the device node type to open, PRIMARY, CONTROL or RENDER
* \param type the device node type to open, PRIMARY or RENDER
*
* \return a file descriptor on success, or a negative value on error.
*
@ -1325,7 +1318,7 @@ drm_public int drmOpenWithType(const char *name, const char *busid, int type)
drm_public int drmOpenControl(int minor)
{
return drmOpenMinor(minor, 0, DRM_NODE_CONTROL);
return -EINVAL;
}
drm_public int drmOpenRender(int minor)
@ -3735,12 +3728,9 @@ static int get_sysctl_pci_bus_info(int maj, int min, drmPciBusInfoPtr info)
switch (type) {
case DRM_NODE_PRIMARY:
break;
case DRM_NODE_CONTROL:
id -= 64;
break;
case DRM_NODE_RENDER:
id -= 128;
break;
break;
}
if (id < 0)
return -EINVAL;
@ -3852,10 +3842,6 @@ drm_public int drmDevicesEqual(drmDevicePtr a, drmDevicePtr b)
static int drmGetNodeType(const char *name)
{
if (strncmp(name, DRM_CONTROL_MINOR_NAME,
sizeof(DRM_CONTROL_MINOR_NAME ) - 1) == 0)
return DRM_NODE_CONTROL;
if (strncmp(name, DRM_RENDER_MINOR_NAME,
sizeof(DRM_RENDER_MINOR_NAME) - 1) == 0)
return DRM_NODE_RENDER;
@ -4684,6 +4670,23 @@ drm_public int drmGetDeviceFromDevId(dev_t find_rdev, uint32_t flags, drmDeviceP
return 0;
}
drm_public int drmGetNodeTypeFromDevId(dev_t devid)
{
int maj, min, node_type;
maj = major(devid);
min = minor(devid);
if (!drmNodeIsDRM(maj, min))
return -EINVAL;
node_type = drmGetMinorType(maj, min);
if (node_type == -1)
return -ENODEV;
return node_type;
}
/**
* Get information about the opened drm device
*
@ -5101,6 +5104,20 @@ drm_public int drmSyncobjTransfer(int fd,
return ret;
}
drm_public int drmSyncobjEventfd(int fd, uint32_t handle, uint64_t point, int ev_fd,
uint32_t flags)
{
struct drm_syncobj_eventfd args;
memclear(args);
args.handle = handle;
args.point = point;
args.fd = ev_fd;
args.flags = flags;
return drmIoctl(fd, DRM_IOCTL_SYNCOBJ_EVENTFD, &args);
}
static char *
drmGetFormatModifierFromSimpleTokens(uint64_t modifier)
{

View File

@ -44,7 +44,7 @@ extern "C" {
#endif
#ifndef DRM_MAX_MINOR
#define DRM_MAX_MINOR 16
#define DRM_MAX_MINOR 64 /* deprecated */
#endif
#if defined(__linux__)
@ -78,12 +78,12 @@ extern "C" {
#define DRM_DIR_NAME "/dev/dri"
#define DRM_PRIMARY_MINOR_NAME "card"
#define DRM_CONTROL_MINOR_NAME "controlD"
#define DRM_CONTROL_MINOR_NAME "controlD" /* deprecated */
#define DRM_RENDER_MINOR_NAME "renderD"
#define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */
#define DRM_DEV_NAME "%s/" DRM_PRIMARY_MINOR_NAME "%d"
#define DRM_CONTROL_DEV_NAME "%s/" DRM_CONTROL_MINOR_NAME "%d"
#define DRM_CONTROL_DEV_NAME "%s/" DRM_CONTROL_MINOR_NAME "%d" /* deprecated */
#define DRM_RENDER_DEV_NAME "%s/" DRM_RENDER_MINOR_NAME "%d"
#define DRM_NODE_NAME_MAX \
@ -91,7 +91,7 @@ extern "C" {
+ MAX3(sizeof(DRM_PRIMARY_MINOR_NAME), \
sizeof(DRM_CONTROL_MINOR_NAME), \
sizeof(DRM_RENDER_MINOR_NAME)) \
+ sizeof("144") /* highest possible node number */ \
+ sizeof("1048575") /* highest possible node number 2^MINORBITS - 1 */ \
+ 1) /* NULL-terminator */
#define DRM_ERR_NO_DEVICE (-1001)
@ -589,14 +589,14 @@ extern int drmAvailable(void);
extern int drmOpen(const char *name, const char *busid);
#define DRM_NODE_PRIMARY 0
#define DRM_NODE_CONTROL 1
#define DRM_NODE_CONTROL 1 /* deprecated: never returned */
#define DRM_NODE_RENDER 2
#define DRM_NODE_MAX 3
extern int drmOpenWithType(const char *name, const char *busid,
int type);
extern int drmOpenControl(int minor);
extern int drmOpenControl(int minor); /* deprecated: always fails */
extern int drmOpenRender(int minor);
extern int drmClose(int fd);
extern drmVersionPtr drmGetVersion(int fd);
@ -801,7 +801,7 @@ extern int drmHandleEvent(int fd, drmEventContextPtr evctx);
extern char *drmGetDeviceNameFromFd(int fd);
/* Improved version of drmGetDeviceNameFromFd which attributes for any type of
* device/node - card, control or renderD.
* device/node - card or renderD.
*/
extern char *drmGetDeviceNameFromFd2(int fd);
extern int drmGetNodeTypeFromFd(int fd);
@ -912,6 +912,13 @@ extern int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_device
extern int drmGetDeviceFromDevId(dev_t dev_id, uint32_t flags, drmDevicePtr *device);
/**
* Get the node type (DRM_NODE_PRIMARY or DRM_NODE_RENDER) from a device ID.
*
* Returns negative errno on error.
*/
extern int drmGetNodeTypeFromDevId(dev_t devid);
extern int drmDevicesEqual(drmDevicePtr a, drmDevicePtr b);
extern int drmSyncobjCreate(int fd, uint32_t flags, uint32_t *handle);
@ -940,6 +947,8 @@ extern int drmSyncobjTransfer(int fd,
uint32_t dst_handle, uint64_t dst_point,
uint32_t src_handle, uint64_t src_point,
uint32_t flags);
extern int drmSyncobjEventfd(int fd, uint32_t handle, uint64_t point, int ev_fd,
uint32_t flags);
extern char *
drmGetFormatModifierVendor(uint64_t modifier);

View File

@ -320,6 +320,16 @@ drm_public int drmModeRmFB(int fd, uint32_t bufferId)
return DRM_IOCTL(fd, DRM_IOCTL_MODE_RMFB, &bufferId);
}
drm_public int drmModeCloseFB(int fd, uint32_t buffer_id)
{
struct drm_mode_closefb closefb;
memclear(closefb);
closefb.fb_id = buffer_id;
return DRM_IOCTL(fd, DRM_IOCTL_MODE_CLOSEFB, &closefb);
}
drm_public drmModeFBPtr drmModeGetFB(int fd, uint32_t buf)
{
struct drm_mode_fb_cmd info;
@ -1004,8 +1014,8 @@ drm_public int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
}
drm_public int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,
uint16_t *red, uint16_t *green,
uint16_t *blue)
const uint16_t *red, const uint16_t *green,
const uint16_t *blue)
{
struct drm_mode_crtc_lut l;

View File

@ -314,6 +314,13 @@ int drmModeAddFB2WithModifiers(int fd, uint32_t width, uint32_t height,
*/
extern int drmModeRmFB(int fd, uint32_t bufferId);
/**
* Close a framebuffer.
*
* Same as drmModeRmFB(), except it doesn't implicitly disable planes and CRTCs.
*/
extern int drmModeCloseFB(int fd, uint32_t buffer_id);
/**
* Mark a region of a framebuffer as dirty.
*/
@ -416,7 +423,7 @@ extern int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t p
extern int drmCheckModesettingSupported(const char *busid);
extern int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,
uint16_t *red, uint16_t *green, uint16_t *blue);
const uint16_t *red, const uint16_t *green, const uint16_t *blue);
extern int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
uint16_t *red, uint16_t *green, uint16_t *blue);
extern int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,