OSDN Git Service

6cd3f5b410ef67c5ab9462e369522fbb3a75a4dc
[android-x86/external-minigbm.git] / i915_private.c
1 /*
2  * Copyright 2017 The Chromium OS 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 #ifdef DRV_I915
8
9 #include <assert.h>
10 #include <errno.h>
11 #include <i915_drm.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <sys/mman.h>
15 #include <drm_fourcc.h>
16 #include <xf86drm.h>
17
18 #include "drv_priv.h"
19 #include "helpers.h"
20 #include "util.h"
21 #include "i915_private.h"
22
23 static const uint32_t private_linear_source_formats[] = { DRM_FORMAT_R16,    DRM_FORMAT_NV16,
24                                                           DRM_FORMAT_YUV420, DRM_FORMAT_YUV422,
25                                                           DRM_FORMAT_YUV444, DRM_FORMAT_NV21,
26                                                           DRM_FORMAT_P010, DRM_FORMAT_RGB888, DRM_FORMAT_BGR888,
27                                                           DRM_FORMAT_ABGR2101010 };
28
29 static const uint32_t private_source_formats[] = { DRM_FORMAT_P010, DRM_FORMAT_NV12_Y_TILED_INTEL };
30
31 #if !defined(DRM_CAP_CURSOR_WIDTH)
32 #define DRM_CAP_CURSOR_WIDTH 0x8
33 #endif
34
35 #if !defined(DRM_CAP_CURSOR_HEIGHT)
36 #define DRM_CAP_CURSOR_HEIGHT 0x9
37 #endif
38
39 static const uint32_t kDefaultCursorWidth = 64;
40 static const uint32_t kDefaultCursorHeight = 64;
41
42 #define BO_USE_CAMERA_MASK BO_USE_CAMERA_READ | BO_USE_SCANOUT | BO_USE_CAMERA_WRITE
43
44 static void get_preferred_cursor_attributes(uint32_t drm_fd, uint64_t *cursor_width,
45                                             uint64_t *cursor_height)
46 {
47         uint64_t width = 0, height = 0;
48         if (drmGetCap(drm_fd, DRM_CAP_CURSOR_WIDTH, &width)) {
49                 fprintf(stderr, "cannot get cursor width. \n");
50         } else if (drmGetCap(drm_fd, DRM_CAP_CURSOR_HEIGHT, &height)) {
51                 fprintf(stderr, "cannot get cursor height. \n");
52         }
53
54         if (!width)
55                 width = kDefaultCursorWidth;
56
57         *cursor_width = width;
58
59         if (!height)
60                 height = kDefaultCursorHeight;
61
62         *cursor_height = height;
63 }
64
65 int i915_private_init(struct driver *drv, uint64_t *cursor_width, uint64_t *cursor_height)
66 {
67         get_preferred_cursor_attributes(drv->fd, cursor_width, cursor_height);
68         return 0;
69 }
70
71 int i915_private_add_combinations(struct driver *drv)
72 {
73         struct format_metadata metadata;
74         uint64_t render_flags, texture_flags;
75
76         render_flags = BO_USE_RENDER_MASK;
77         texture_flags = BO_USE_TEXTURE_MASK;
78
79         metadata.tiling = I915_TILING_NONE;
80         metadata.priority = 1;
81         metadata.modifier = DRM_FORMAT_MOD_NONE;
82
83         drv_modify_combination(drv, DRM_FORMAT_ABGR8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT);
84         drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata,
85                                BO_USE_RENDERING | BO_USE_TEXTURE | BO_USE_CAMERA_MASK);
86         drv_modify_combination(drv, DRM_FORMAT_YUYV, &metadata,
87                                BO_USE_TEXTURE | BO_USE_CAMERA_MASK | BO_USE_RENDERING);
88         drv_modify_combination(drv, DRM_FORMAT_VYUY, &metadata,
89                                BO_USE_TEXTURE | BO_USE_CAMERA_MASK | BO_USE_RENDERING);
90         drv_modify_combination(drv, DRM_FORMAT_UYVY, &metadata,
91                                BO_USE_TEXTURE | BO_USE_CAMERA_MASK | BO_USE_RENDERING);
92         drv_modify_combination(drv, DRM_FORMAT_YVYU, &metadata,
93                                BO_USE_TEXTURE | BO_USE_CAMERA_MASK | BO_USE_RENDERING);
94         drv_modify_combination(drv, DRM_FORMAT_YVU420_ANDROID, &metadata,
95                                BO_USE_TEXTURE | BO_USE_CAMERA_MASK);
96         drv_modify_combination(drv, DRM_FORMAT_RGB565, &metadata, BO_USE_CAMERA_MASK);
97
98         /* Media/Camera expect these formats support. */
99         metadata.tiling = I915_TILING_NONE;
100         metadata.priority = 1;
101         metadata.modifier = DRM_FORMAT_MOD_NONE;
102         drv_add_combinations(drv, private_linear_source_formats,
103                              ARRAY_SIZE(private_linear_source_formats), &metadata,
104                              texture_flags | BO_USE_CAMERA_MASK);
105
106         metadata.tiling = I915_TILING_Y;
107         metadata.priority = 3;
108         metadata.modifier = I915_FORMAT_MOD_Y_TILED;
109         drv_add_combinations(drv, private_source_formats, ARRAY_SIZE(private_source_formats),
110                              &metadata, texture_flags | BO_USE_CAMERA_MASK);
111
112         texture_flags &= ~BO_USE_RENDERSCRIPT;
113         texture_flags &= ~BO_USE_SW_WRITE_OFTEN;
114         texture_flags &= ~BO_USE_SW_READ_OFTEN;
115         texture_flags &= ~BO_USE_LINEAR;
116
117         metadata.tiling = I915_TILING_X;
118         metadata.priority = 2;
119         metadata.modifier = I915_FORMAT_MOD_X_TILED;
120
121         int ret = drv_add_combinations(drv, private_linear_source_formats,
122                                        ARRAY_SIZE(private_linear_source_formats), &metadata,
123                                        texture_flags | BO_USE_CAMERA_MASK);
124         if (ret)
125                 return ret;
126
127         return 0;
128 }
129
130 void i915_private_align_dimensions(uint32_t format, uint32_t *vertical_alignment)
131 {
132         switch (format) {
133         case DRM_FORMAT_NV12_Y_TILED_INTEL:
134                 *vertical_alignment = 64;
135                 break;
136         }
137 }
138
139 uint32_t i915_private_bpp_from_format(uint32_t format, size_t plane)
140 {
141         assert(plane < drv_num_planes_from_format(format));
142
143         switch (format) {
144         case DRM_FORMAT_NV12_Y_TILED_INTEL:
145                 return (plane == 0) ? 8 : 4;
146         case DRM_FORMAT_P010:
147                 return (plane == 0) ? 16 : 8;
148         case DRM_FORMAT_YUV420:
149         case DRM_FORMAT_YUV422:
150         case DRM_FORMAT_YUV444:
151         case DRM_FORMAT_NV16:
152                 return 8;
153         case DRM_FORMAT_R16:
154                 return 16;
155         case DRM_FORMAT_ABGR2101010:
156                 return 32;
157         }
158
159         fprintf(stderr, "drv: UNKNOWN FORMAT %d\n", format);
160         return 0;
161 }
162
163 void i915_private_vertical_subsampling_from_format(uint32_t *vertical_subsampling, uint32_t format,
164                                                    size_t plane)
165 {
166         switch (format) {
167         case DRM_FORMAT_NV12_Y_TILED_INTEL:
168         case DRM_FORMAT_YUV420:
169         case DRM_FORMAT_P010:
170                 *vertical_subsampling = (plane == 0) ? 1 : 2;
171                 break;
172         default:
173                 *vertical_subsampling = 1;
174         }
175 }
176
177 size_t i915_private_num_planes_from_format(uint32_t format)
178 {
179         switch (format) {
180         case DRM_FORMAT_R16:
181         case DRM_FORMAT_ABGR2101010:
182                 return 1;
183         case DRM_FORMAT_NV12_Y_TILED_INTEL:
184         case DRM_FORMAT_NV16:
185         case DRM_FORMAT_P010:
186                 return 2;
187         case DRM_FORMAT_YUV420:
188         case DRM_FORMAT_YUV422:
189         case DRM_FORMAT_YUV444:
190                 return 3;
191         }
192
193         fprintf(stderr, "drv: UNKNOWN FORMAT %d\n", format);
194         return 0;
195 }
196
197 uint32_t i915_private_resolve_format(uint32_t format, uint64_t usage, uint32_t *resolved_format)
198 {
199         switch (format) {
200         case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED:
201                 /* KBL camera subsystem requires NV12. */
202                 if (usage & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)) {
203                         *resolved_format = DRM_FORMAT_NV12;
204                         return 1;
205                 }
206
207                 if (usage & BO_USE_TEXTURE) {
208                         *resolved_format = DRM_FORMAT_ABGR8888;
209                         return 1;
210                 }
211         }
212
213         return 0;
214 }
215
216 #endif