Skip to main content

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::{Error, anyhow};
6use fidl_fuchsia_images2 as fimages2;
7use fidl_fuchsia_sysmem as fsysmem;
8use vk_sys as vk;
9
10pub fn drm_modifier_to_sysmem_modifier_2(
11    modifier: u64,
12) -> Result<fimages2::PixelFormatModifier, Error> {
13    match modifier {
14        DRM_FORMAT_MOD_LINEAR => Ok(fimages2::PixelFormatModifier::Linear),
15        I915_FORMAT_MOD_X_TILED => Ok(fimages2::PixelFormatModifier::IntelI915XTiled),
16        I915_FORMAT_MOD_Y_TILED => Ok(fimages2::PixelFormatModifier::IntelI915YTiled),
17        I915_FORMAT_MOD_YF_TILED => Ok(fimages2::PixelFormatModifier::IntelI915YfTiled),
18        I915_FORMAT_MOD_Y_TILED_CCS => Ok(fimages2::PixelFormatModifier::IntelI915YTiledCcs),
19        I915_FORMAT_MOD_YF_TILED_CCS => Ok(fimages2::PixelFormatModifier::IntelI915YfTiledCcs),
20        DRM_FORMAT_MOD_PVR_FBCDC_8X8_V14 => Ok(fimages2::PixelFormatModifier::PvrFbcdc8X8V14),
21        DRM_FORMAT_MOD_PVR_FBCDC_16X4_V14 => Ok(fimages2::PixelFormatModifier::PvrFbcdc16X4V14),
22        _ => Err(anyhow!("Unsupported modifier.")),
23    }
24}
25
26pub fn drm_modifier_to_sysmem_modifier(modifier: u64) -> Result<u64, Error> {
27    match modifier {
28        DRM_FORMAT_MOD_LINEAR => Ok(fsysmem::FORMAT_MODIFIER_LINEAR),
29        I915_FORMAT_MOD_X_TILED => Ok(fsysmem::FORMAT_MODIFIER_INTEL_I915_X_TILED),
30        I915_FORMAT_MOD_Y_TILED => Ok(fsysmem::FORMAT_MODIFIER_INTEL_I915_Y_TILED),
31        I915_FORMAT_MOD_YF_TILED => Ok(fsysmem::FORMAT_MODIFIER_INTEL_I915_YF_TILED),
32        I915_FORMAT_MOD_Y_TILED_CCS => Ok(fsysmem::FORMAT_MODIFIER_INTEL_I915_Y_TILED_CCS),
33        I915_FORMAT_MOD_YF_TILED_CCS => Ok(fsysmem::FORMAT_MODIFIER_INTEL_I915_YF_TILED_CCS),
34        _ => Err(anyhow!("Unsupported modifier.")),
35    }
36}
37
38pub fn min_bytes_per_row(drm_format: u32, width: u32) -> Result<u32, Error> {
39    match drm_format {
40        format
41            if format == DRM_FORMAT_ARGB8888
42                || format == DRM_FORMAT_XRGB8888
43                || format == DRM_FORMAT_ABGR8888
44                || format == DRM_FORMAT_XBGR8888 =>
45        {
46            Ok(width * 4)
47        }
48        _ => Err(anyhow!("Unsupported format.")),
49    }
50}
51
52pub fn drm_format_to_vulkan_format(drm_format: u32) -> Result<u32, Error> {
53    match drm_format {
54        DRM_FORMAT_ARGB8888 | DRM_FORMAT_XRGB8888 => Ok(vk::FORMAT_B8G8R8A8_UNORM),
55        DRM_FORMAT_ABGR8888 | DRM_FORMAT_XBGR8888 => Ok(vk::FORMAT_R8G8B8A8_UNORM),
56        DRM_FORMAT_RGB565 => Ok(vk::FORMAT_R5G6B5_UNORM_PACK16),
57        _ => Err(anyhow!("Unsupported format.")),
58    }
59}
60
61pub fn drm_format_to_sysmem_format(drm_format: u32) -> Result<fsysmem::PixelFormatType, Error> {
62    match drm_format {
63        DRM_FORMAT_ARGB8888 | DRM_FORMAT_XRGB8888 => Ok(fsysmem::PixelFormatType::Bgra32),
64        DRM_FORMAT_ABGR8888 | DRM_FORMAT_XBGR8888 => Ok(fsysmem::PixelFormatType::R8G8B8A8),
65        DRM_FORMAT_RGB565 => Ok(fsysmem::PixelFormatType::Rgb565),
66        _ => Err(anyhow!("Unsupported format.")),
67    }
68}
69
70pub fn drm_format_to_images2_format(drm_format: u32) -> Result<fimages2::PixelFormat, Error> {
71    match drm_format {
72        DRM_FORMAT_ARGB8888 | DRM_FORMAT_XRGB8888 => Ok(fimages2::PixelFormat::B8G8R8A8),
73        DRM_FORMAT_ABGR8888 | DRM_FORMAT_XBGR8888 => Ok(fimages2::PixelFormat::R8G8B8A8),
74        DRM_FORMAT_RGB565 => Ok(fimages2::PixelFormat::R5G6B5),
75        _ => Err(anyhow!("Unsupported format.")),
76    }
77}
78
79pub fn sysmem_modifier_to_drm_modifier_2(
80    modifier: fimages2::PixelFormatModifier,
81) -> Result<u64, Error> {
82    match modifier {
83        fimages2::PixelFormatModifier::Linear => Ok(DRM_FORMAT_MOD_LINEAR),
84        fimages2::PixelFormatModifier::IntelI915XTiled => Ok(I915_FORMAT_MOD_X_TILED),
85        fimages2::PixelFormatModifier::IntelI915YTiled => Ok(I915_FORMAT_MOD_Y_TILED),
86        fimages2::PixelFormatModifier::IntelI915YfTiled => Ok(I915_FORMAT_MOD_YF_TILED),
87        fimages2::PixelFormatModifier::IntelI915YTiledCcs => Ok(I915_FORMAT_MOD_Y_TILED_CCS),
88        fimages2::PixelFormatModifier::IntelI915YfTiledCcs => Ok(I915_FORMAT_MOD_YF_TILED_CCS),
89        fimages2::PixelFormatModifier::PvrFbcdc8X8V14 => Ok(DRM_FORMAT_MOD_PVR_FBCDC_8X8_V14),
90        fimages2::PixelFormatModifier::PvrFbcdc16X4V14 => Ok(DRM_FORMAT_MOD_PVR_FBCDC_16X4_V14),
91        _ => Err(anyhow!("Unsupported modifier.")),
92    }
93}
94
95pub fn sysmem_modifier_to_drm_modifier(modifier: u64) -> Result<u64, Error> {
96    match modifier {
97        fsysmem::FORMAT_MODIFIER_LINEAR => Ok(DRM_FORMAT_MOD_LINEAR),
98        fsysmem::FORMAT_MODIFIER_INTEL_I915_X_TILED => Ok(I915_FORMAT_MOD_X_TILED),
99        fsysmem::FORMAT_MODIFIER_INTEL_I915_Y_TILED => Ok(I915_FORMAT_MOD_Y_TILED),
100        fsysmem::FORMAT_MODIFIER_INTEL_I915_YF_TILED => Ok(I915_FORMAT_MOD_YF_TILED),
101        fsysmem::FORMAT_MODIFIER_INTEL_I915_Y_TILED_CCS => Ok(I915_FORMAT_MOD_Y_TILED_CCS),
102        fsysmem::FORMAT_MODIFIER_INTEL_I915_YF_TILED_CCS => Ok(I915_FORMAT_MOD_YF_TILED_CCS),
103        _ => Err(anyhow!("Unsupported modifier.")),
104    }
105}
106
107const fn fourcc_code(a: u8, b: u8, c: u8, d: u8) -> u32 {
108    let a32 = a as u32;
109    let b32 = (b as u32) << 8;
110    let c32 = (c as u32) << 16;
111    let d32 = (d as u32) << 24;
112    a32 | b32 | c32 | d32
113}
114
115const fn fourcc_mod_code(vendor: u64, value: u64) -> u64 {
116    vendor << 56 | (value & 0x00ffffffffffffff)
117}
118
119pub const DRM_FORMAT_MOD_VENDOR_NONE: u64 = 0;
120pub const DRM_FORMAT_MOD_VENDOR_INTEL: u64 = 0x01;
121
122// The value matches the preprocessor macro with the same name in:
123// https://fuchsia.googlesource.com/third_party/imgtec-pvr-rgx-km/+/refs/heads/main/include/public/powervr/img_drm_fourcc.h
124pub const DRM_FORMAT_MOD_VENDOR_PVR: u64 = 0x92;
125
126pub const DRM_FORMAT_MOD_INVALID: u64 =
127    fourcc_mod_code(DRM_FORMAT_MOD_VENDOR_NONE, DRM_FORMAT_MOD_RESERVED);
128
129pub const DRM_FORMAT_MOD_RESERVED: u64 = (1 << 56) - 1;
130pub const DRM_FORMAT_MOD_LINEAR: u64 = fourcc_mod_code(DRM_FORMAT_MOD_VENDOR_NONE, 0);
131pub const I915_FORMAT_MOD_X_TILED: u64 = fourcc_mod_code(DRM_FORMAT_MOD_VENDOR_INTEL, 1);
132pub const I915_FORMAT_MOD_Y_TILED: u64 = fourcc_mod_code(DRM_FORMAT_MOD_VENDOR_INTEL, 2);
133pub const I915_FORMAT_MOD_YF_TILED: u64 = fourcc_mod_code(DRM_FORMAT_MOD_VENDOR_INTEL, 3);
134pub const I915_FORMAT_MOD_Y_TILED_CCS: u64 = fourcc_mod_code(DRM_FORMAT_MOD_VENDOR_INTEL, 4);
135pub const I915_FORMAT_MOD_YF_TILED_CCS: u64 = fourcc_mod_code(DRM_FORMAT_MOD_VENDOR_INTEL, 5);
136
137// The values match the preprocessor macro with the same name in:
138// https://fuchsia.googlesource.com/third_party/imgtec-pvr-rgx-km/+/refs/heads/main/include/public/powervr/img_drm_fourcc.h
139pub const DRM_FORMAT_MOD_PVR_FBCDC_8X8_V14: u64 = fourcc_mod_code(DRM_FORMAT_MOD_VENDOR_PVR, 34);
140pub const DRM_FORMAT_MOD_PVR_FBCDC_16X4_V14: u64 = fourcc_mod_code(DRM_FORMAT_MOD_VENDOR_PVR, 39);
141
142pub const DRM_FORMAT_XRGB8888: u32 = fourcc_code(b'X', b'R', b'2', b'4');
143pub const DRM_FORMAT_XBGR8888: u32 = fourcc_code(b'X', b'B', b'2', b'4');
144pub const DRM_FORMAT_ARGB8888: u32 = fourcc_code(b'A', b'R', b'2', b'4');
145pub const DRM_FORMAT_ABGR8888: u32 = fourcc_code(b'A', b'B', b'2', b'4');
146pub const DRM_FORMAT_RGB565: u32 = fourcc_code(b'R', b'G', b'1', b'6');