fuchsia_image_format/
linux_drm.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use anyhow::{anyhow, Error};
6use {fidl_fuchsia_images2 as fimages2, fidl_fuchsia_sysmem as fsysmem, vk_sys as vk};
7
8pub fn drm_modifier_to_sysmem_modifier_2(
9    modifier: u64,
10) -> Result<fimages2::PixelFormatModifier, Error> {
11    match modifier {
12        DRM_FORMAT_MOD_LINEAR => Ok(fimages2::PixelFormatModifier::Linear),
13        I915_FORMAT_MOD_X_TILED => Ok(fimages2::PixelFormatModifier::IntelI915XTiled),
14        I915_FORMAT_MOD_Y_TILED => Ok(fimages2::PixelFormatModifier::IntelI915YTiled),
15        I915_FORMAT_MOD_YF_TILED => Ok(fimages2::PixelFormatModifier::IntelI915YfTiled),
16        I915_FORMAT_MOD_Y_TILED_CCS => Ok(fimages2::PixelFormatModifier::IntelI915YTiledCcs),
17        I915_FORMAT_MOD_YF_TILED_CCS => Ok(fimages2::PixelFormatModifier::IntelI915YfTiledCcs),
18        _ => Err(anyhow!("Unsupported modifier.")),
19    }
20}
21
22pub fn drm_modifier_to_sysmem_modifier(modifier: u64) -> Result<u64, Error> {
23    match modifier {
24        DRM_FORMAT_MOD_LINEAR => Ok(fsysmem::FORMAT_MODIFIER_LINEAR),
25        I915_FORMAT_MOD_X_TILED => Ok(fsysmem::FORMAT_MODIFIER_INTEL_I915_X_TILED),
26        I915_FORMAT_MOD_Y_TILED => Ok(fsysmem::FORMAT_MODIFIER_INTEL_I915_Y_TILED),
27        I915_FORMAT_MOD_YF_TILED => Ok(fsysmem::FORMAT_MODIFIER_INTEL_I915_YF_TILED),
28        I915_FORMAT_MOD_Y_TILED_CCS => Ok(fsysmem::FORMAT_MODIFIER_INTEL_I915_Y_TILED_CCS),
29        I915_FORMAT_MOD_YF_TILED_CCS => Ok(fsysmem::FORMAT_MODIFIER_INTEL_I915_YF_TILED_CCS),
30        _ => Err(anyhow!("Unsupported modifier.")),
31    }
32}
33
34pub fn min_bytes_per_row(drm_format: u32, width: u32) -> Result<u32, Error> {
35    match drm_format {
36        format
37            if format == DRM_FORMAT_ARGB8888
38                || format == DRM_FORMAT_XRGB8888
39                || format == DRM_FORMAT_ABGR8888
40                || format == DRM_FORMAT_XBGR8888 =>
41        {
42            Ok(width * 4)
43        }
44        _ => Err(anyhow!("Unsupported format.")),
45    }
46}
47
48pub fn drm_format_to_vulkan_format(drm_format: u32) -> Result<u32, Error> {
49    match drm_format {
50        DRM_FORMAT_ARGB8888 | DRM_FORMAT_XRGB8888 => Ok(vk::FORMAT_B8G8R8A8_UNORM),
51        DRM_FORMAT_ABGR8888 | DRM_FORMAT_XBGR8888 => Ok(vk::FORMAT_R8G8B8A8_UNORM),
52        DRM_FORMAT_RGB565 => Ok(vk::FORMAT_R5G6B5_UNORM_PACK16),
53        _ => Err(anyhow!("Unsupported format.")),
54    }
55}
56
57pub fn drm_format_to_sysmem_format(drm_format: u32) -> Result<fsysmem::PixelFormatType, Error> {
58    match drm_format {
59        DRM_FORMAT_ARGB8888 | DRM_FORMAT_XRGB8888 => Ok(fsysmem::PixelFormatType::Bgra32),
60        DRM_FORMAT_ABGR8888 | DRM_FORMAT_XBGR8888 => Ok(fsysmem::PixelFormatType::R8G8B8A8),
61        DRM_FORMAT_RGB565 => Ok(fsysmem::PixelFormatType::Rgb565),
62        _ => Err(anyhow!("Unsupported format.")),
63    }
64}
65
66pub fn drm_format_to_images2_format(drm_format: u32) -> Result<fimages2::PixelFormat, Error> {
67    match drm_format {
68        DRM_FORMAT_ARGB8888 | DRM_FORMAT_XRGB8888 => Ok(fimages2::PixelFormat::B8G8R8A8),
69        DRM_FORMAT_ABGR8888 | DRM_FORMAT_XBGR8888 => Ok(fimages2::PixelFormat::R8G8B8A8),
70        DRM_FORMAT_RGB565 => Ok(fimages2::PixelFormat::R5G6B5),
71        _ => Err(anyhow!("Unsupported format.")),
72    }
73}
74
75pub fn sysmem_modifier_to_drm_modifier_2(
76    modifier: fimages2::PixelFormatModifier,
77) -> Result<u64, Error> {
78    match modifier {
79        fimages2::PixelFormatModifier::Linear => Ok(DRM_FORMAT_MOD_LINEAR),
80        fimages2::PixelFormatModifier::IntelI915XTiled => Ok(I915_FORMAT_MOD_X_TILED),
81        fimages2::PixelFormatModifier::IntelI915YTiled => Ok(I915_FORMAT_MOD_Y_TILED),
82        fimages2::PixelFormatModifier::IntelI915YfTiled => Ok(I915_FORMAT_MOD_YF_TILED),
83        fimages2::PixelFormatModifier::IntelI915YTiledCcs => Ok(I915_FORMAT_MOD_Y_TILED_CCS),
84        fimages2::PixelFormatModifier::IntelI915YfTiledCcs => Ok(I915_FORMAT_MOD_YF_TILED_CCS),
85        _ => Err(anyhow!("Unsupported modifier.")),
86    }
87}
88
89pub fn sysmem_modifier_to_drm_modifier(modifier: u64) -> Result<u64, Error> {
90    match modifier {
91        fsysmem::FORMAT_MODIFIER_LINEAR => Ok(DRM_FORMAT_MOD_LINEAR),
92        fsysmem::FORMAT_MODIFIER_INTEL_I915_X_TILED => Ok(I915_FORMAT_MOD_X_TILED),
93        fsysmem::FORMAT_MODIFIER_INTEL_I915_Y_TILED => Ok(I915_FORMAT_MOD_Y_TILED),
94        fsysmem::FORMAT_MODIFIER_INTEL_I915_YF_TILED => Ok(I915_FORMAT_MOD_YF_TILED),
95        fsysmem::FORMAT_MODIFIER_INTEL_I915_Y_TILED_CCS => Ok(I915_FORMAT_MOD_Y_TILED_CCS),
96        fsysmem::FORMAT_MODIFIER_INTEL_I915_YF_TILED_CCS => Ok(I915_FORMAT_MOD_YF_TILED_CCS),
97        _ => Err(anyhow!("Unsupported modifier.")),
98    }
99}
100
101const fn fourcc_code(a: u8, b: u8, c: u8, d: u8) -> u32 {
102    let a32 = a as u32;
103    let b32 = (b as u32) << 8;
104    let c32 = (c as u32) << 16;
105    let d32 = (d as u32) << 24;
106    a32 | b32 | c32 | d32
107}
108
109const fn fourcc_mod_code(vendor: u64, value: u64) -> u64 {
110    vendor << 56 | (value & 0x00ffffffffffffff)
111}
112
113pub const DRM_FORMAT_MOD_VENDOR_NONE: u64 = 0;
114pub const DRM_FORMAT_MOD_VENDOR_INTEL: u64 = 0x01;
115
116pub const DRM_FORMAT_MOD_INVALID: u64 =
117    fourcc_mod_code(DRM_FORMAT_MOD_VENDOR_NONE, DRM_FORMAT_MOD_RESERVED);
118
119pub const DRM_FORMAT_MOD_RESERVED: u64 = (1 << 56) - 1;
120pub const DRM_FORMAT_MOD_LINEAR: u64 = fourcc_mod_code(DRM_FORMAT_MOD_VENDOR_NONE, 0);
121pub const I915_FORMAT_MOD_X_TILED: u64 = fourcc_mod_code(DRM_FORMAT_MOD_VENDOR_INTEL, 1);
122pub const I915_FORMAT_MOD_Y_TILED: u64 = fourcc_mod_code(DRM_FORMAT_MOD_VENDOR_INTEL, 2);
123pub const I915_FORMAT_MOD_YF_TILED: u64 = fourcc_mod_code(DRM_FORMAT_MOD_VENDOR_INTEL, 3);
124pub const I915_FORMAT_MOD_Y_TILED_CCS: u64 = fourcc_mod_code(DRM_FORMAT_MOD_VENDOR_INTEL, 4);
125pub const I915_FORMAT_MOD_YF_TILED_CCS: u64 = fourcc_mod_code(DRM_FORMAT_MOD_VENDOR_INTEL, 5);
126
127pub const DRM_FORMAT_XRGB8888: u32 = fourcc_code(b'X', b'R', b'2', b'4');
128pub const DRM_FORMAT_XBGR8888: u32 = fourcc_code(b'X', b'B', b'2', b'4');
129pub const DRM_FORMAT_ARGB8888: u32 = fourcc_code(b'A', b'R', b'2', b'4');
130pub const DRM_FORMAT_ABGR8888: u32 = fourcc_code(b'A', b'B', b'2', b'4');
131pub const DRM_FORMAT_RGB565: u32 = fourcc_code(b'R', b'G', b'1', b'6');