1 //
2 // Copyright 2021 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // dma_buf_utils.cpp: Utilities to interact with Linux dma bufs.
8
9 #include "dma_buf_utils.h"
10
11 #include "common/debug.h"
12
13 #include <sys/stat.h>
14 #include <sys/time.h>
15 #include <sys/types.h>
16 #include <unistd.h>
17
18 #include <array>
19
20 // Refer to:
21 // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/drm/drm_fourcc.h
22 // https://source.chromium.org/chromium/chromium/src/+/main:ui/gl/gl_image_native_pixmap.cc;l=24
23 #define FOURCC(a, b, c, d) \
24 ((static_cast<uint32_t>(a)) | (static_cast<uint32_t>(b) << 8) | \
25 (static_cast<uint32_t>(c) << 16) | (static_cast<uint32_t>(d) << 24))
26
27 #define DRM_FORMAT_R8 FOURCC('R', '8', ' ', ' ')
28 #define DRM_FORMAT_R16 FOURCC('R', '1', '6', ' ')
29 #define DRM_FORMAT_GR88 FOURCC('G', 'R', '8', '8')
30 #define DRM_FORMAT_RGB565 FOURCC('R', 'G', '1', '6')
31 #define DRM_FORMAT_RGB888 FOURCC('R', 'G', '2', '4')
32 #define DRM_FORMAT_BGR888 FOURCC('B', 'G', '2', '4')
33 #define DRM_FORMAT_ARGB8888 FOURCC('A', 'R', '2', '4')
34 #define DRM_FORMAT_ABGR8888 FOURCC('A', 'B', '2', '4')
35 #define DRM_FORMAT_XRGB8888 FOURCC('X', 'R', '2', '4')
36 #define DRM_FORMAT_XBGR8888 FOURCC('X', 'B', '2', '4')
37 #define DRM_FORMAT_ABGR2101010 FOURCC('A', 'B', '3', '0')
38 #define DRM_FORMAT_ARGB2101010 FOURCC('A', 'R', '3', '0')
39 #define DRM_FORMAT_YVU420 FOURCC('Y', 'V', '1', '2')
40 #define DRM_FORMAT_NV12 FOURCC('N', 'V', '1', '2')
41 #define DRM_FORMAT_P010 FOURCC('P', '0', '1', '0')
42
43 namespace angle
44 {
DrmFourCCFormatToGLInternalFormat(int fourccFormat,bool * isYUV)45 GLenum DrmFourCCFormatToGLInternalFormat(int fourccFormat, bool *isYUV)
46 {
47 *isYUV = false;
48
49 switch (fourccFormat)
50 {
51 case DRM_FORMAT_R8:
52 return GL_R8;
53 case DRM_FORMAT_R16:
54 return GL_R16_EXT;
55 case DRM_FORMAT_GR88:
56 return GL_RG8_EXT;
57 case DRM_FORMAT_ABGR8888:
58 return GL_RGBA8;
59 case DRM_FORMAT_XBGR8888:
60 return GL_RGB8;
61 case DRM_FORMAT_ARGB8888:
62 return GL_BGRA8_EXT;
63 case DRM_FORMAT_XRGB8888:
64 return GL_RGB8;
65 case DRM_FORMAT_ABGR2101010:
66 case DRM_FORMAT_ARGB2101010:
67 return GL_RGB10_A2_EXT;
68 case DRM_FORMAT_RGB565:
69 return GL_RGB565;
70 case DRM_FORMAT_NV12:
71 case DRM_FORMAT_YVU420:
72 case DRM_FORMAT_P010:
73 *isYUV = true;
74 return GL_RGB8;
75 default:
76 UNREACHABLE();
77 WARN() << "Unknown dma_buf format " << fourccFormat
78 << " used to initialize an EGL image.";
79 return GL_RGB8;
80 }
81 }
82
83 #if defined(ANGLE_ENABLE_VULKAN)
VkFormatToDrmFourCCFormat(VkFormat format)84 std::vector<int> VkFormatToDrmFourCCFormat(VkFormat format)
85 {
86 switch (format)
87 {
88 case VK_FORMAT_R8_UNORM:
89 case VK_FORMAT_R8_SRGB:
90 return {DRM_FORMAT_R8};
91 case VK_FORMAT_R16_UNORM:
92 return {DRM_FORMAT_R16};
93 case VK_FORMAT_R8G8_UNORM:
94 case VK_FORMAT_R8G8_SRGB:
95 return {DRM_FORMAT_GR88};
96 case VK_FORMAT_R8G8B8_UNORM:
97 case VK_FORMAT_R8G8B8_SRGB:
98 return {DRM_FORMAT_BGR888};
99 case VK_FORMAT_B8G8R8_UNORM:
100 case VK_FORMAT_B8G8R8_SRGB:
101 return {DRM_FORMAT_RGB888};
102 case VK_FORMAT_R8G8B8A8_UNORM:
103 case VK_FORMAT_R8G8B8A8_SRGB:
104 return {DRM_FORMAT_ABGR8888, DRM_FORMAT_XBGR8888};
105 case VK_FORMAT_B8G8R8A8_UNORM:
106 case VK_FORMAT_B8G8R8A8_SRGB:
107 return {DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888};
108 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
109 return {DRM_FORMAT_ARGB2101010};
110 case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
111 return {DRM_FORMAT_ABGR2101010};
112 case VK_FORMAT_B5G6R5_UNORM_PACK16:
113 return {DRM_FORMAT_RGB565};
114 default:
115 return {};
116 }
117 }
118
DrmFourCCFormatToVkFormats(int fourccFormat)119 std::vector<VkFormat> DrmFourCCFormatToVkFormats(int fourccFormat)
120 {
121 switch (fourccFormat)
122 {
123 case DRM_FORMAT_R8:
124 return {VK_FORMAT_R8_SRGB, VK_FORMAT_R8_UNORM};
125 case DRM_FORMAT_R16:
126 return {VK_FORMAT_R16_UNORM};
127 case DRM_FORMAT_GR88:
128 return {VK_FORMAT_R8G8_SRGB, VK_FORMAT_R8G8_UNORM};
129 case DRM_FORMAT_BGR888:
130 return {VK_FORMAT_R8G8B8_SRGB, VK_FORMAT_R8G8B8_UNORM};
131 case DRM_FORMAT_RGB888:
132 return {VK_FORMAT_B8G8R8_SRGB, VK_FORMAT_B8G8R8_UNORM};
133 case DRM_FORMAT_ABGR8888:
134 case DRM_FORMAT_XBGR8888:
135 return {VK_FORMAT_R8G8B8A8_SRGB, VK_FORMAT_R8G8B8A8_UNORM};
136 case DRM_FORMAT_ARGB8888:
137 case DRM_FORMAT_XRGB8888:
138 return {VK_FORMAT_B8G8R8A8_SRGB, VK_FORMAT_B8G8R8A8_UNORM};
139 case DRM_FORMAT_ABGR2101010:
140 return {VK_FORMAT_A2R10G10B10_UNORM_PACK32};
141 case DRM_FORMAT_ARGB2101010:
142 return {VK_FORMAT_A2B10G10R10_UNORM_PACK32};
143 case DRM_FORMAT_RGB565:
144 return {VK_FORMAT_B5G6R5_UNORM_PACK16};
145 default:
146 WARN() << "Unknown dma_buf format " << fourccFormat
147 << " used to initialize an EGL image.";
148 return {};
149 }
150 }
151 #endif // ANGLE_ENABLE_VULKAN
152
153 } // namespace angle
154