blob: 88360655f6b009934d3ae1c766e11f9e1c26f7ed [file] [log] [blame]
Gurchetan Singh46faf6b2016-08-05 14:40:07 -07001/*
Daniele Castagna7a755de2016-12-16 17:32:30 -05002 * Copyright 2016 The Chromium OS Authors. All rights reserved.
Gurchetan Singh46faf6b2016-08-05 14:40:07 -07003 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6#include <assert.h>
Kristian H. Kristensenb1efbd82016-09-06 11:43:26 -07007#include <errno.h>
Gurchetan Singh46faf6b2016-08-05 14:40:07 -07008#include <fcntl.h>
Gurchetan Singh1647fbe2016-08-03 17:14:55 -07009#include <pthread.h>
Gurchetan Singh46faf6b2016-08-05 14:40:07 -070010#include <stdint.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
Gurchetan Singhef920532016-08-12 16:38:25 -070014#include <sys/mman.h>
Gurchetan Singh46faf6b2016-08-05 14:40:07 -070015#include <xf86drm.h>
16
17#include "drv_priv.h"
18#include "helpers.h"
19#include "util.h"
20
Akshu Agrawal0337d9b2016-07-28 15:35:45 +053021#ifdef DRV_AMDGPU
22extern struct backend backend_amdgpu;
23#endif
Gurchetan Singh46faf6b2016-08-05 14:40:07 -070024extern struct backend backend_cirrus;
25extern struct backend backend_evdi;
26#ifdef DRV_EXYNOS
27extern struct backend backend_exynos;
28#endif
29extern struct backend backend_gma500;
30#ifdef DRV_I915
31extern struct backend backend_i915;
32#endif
33#ifdef DRV_MARVELL
34extern struct backend backend_marvell;
35#endif
36#ifdef DRV_MEDIATEK
37extern struct backend backend_mediatek;
38#endif
Daniele Castagna71db2b52016-12-16 16:24:06 -050039extern struct backend backend_nouveau;
Gurchetan Singh46faf6b2016-08-05 14:40:07 -070040#ifdef DRV_ROCKCHIP
41extern struct backend backend_rockchip;
42#endif
43#ifdef DRV_TEGRA
44extern struct backend backend_tegra;
45#endif
46extern struct backend backend_udl;
Niklas Schulze878fed42017-02-08 15:29:21 +010047#ifdef DRV_VC4
48extern struct backend backend_vc4;
49#endif
Gurchetan Singh5521bde2016-09-30 14:53:32 -070050extern struct backend backend_vgem;
Gurchetan Singh46faf6b2016-08-05 14:40:07 -070051extern struct backend backend_virtio_gpu;
52
53static struct backend *drv_get_backend(int fd)
54{
55 drmVersionPtr drm_version;
56 unsigned int i;
57
58 drm_version = drmGetVersion(fd);
59
60 if (!drm_version)
61 return NULL;
62
63 struct backend *backend_list[] = {
Akshu Agrawal0337d9b2016-07-28 15:35:45 +053064#ifdef DRV_AMDGPU
65 &backend_amdgpu,
66#endif
Gurchetan Singh46faf6b2016-08-05 14:40:07 -070067 &backend_cirrus,
68 &backend_evdi,
69#ifdef DRV_EXYNOS
70 &backend_exynos,
71#endif
72 &backend_gma500,
73#ifdef DRV_I915
74 &backend_i915,
75#endif
76#ifdef DRV_MARVELL
77 &backend_marvell,
78#endif
79#ifdef DRV_MEDIATEK
80 &backend_mediatek,
81#endif
Daniele Castagna71db2b52016-12-16 16:24:06 -050082 &backend_nouveau,
Gurchetan Singh46faf6b2016-08-05 14:40:07 -070083#ifdef DRV_ROCKCHIP
84 &backend_rockchip,
85#endif
86#ifdef DRV_TEGRA
87 &backend_tegra,
88#endif
89 &backend_udl,
Niklas Schulze878fed42017-02-08 15:29:21 +010090#ifdef DRV_VC4
91 &backend_vc4,
92#endif
Gurchetan Singh5521bde2016-09-30 14:53:32 -070093 &backend_vgem,
Gurchetan Singh46faf6b2016-08-05 14:40:07 -070094 &backend_virtio_gpu,
95 };
96
97 for(i = 0; i < ARRAY_SIZE(backend_list); i++)
98 if (!strcmp(drm_version->name, backend_list[i]->name)) {
99 drmFreeVersion(drm_version);
100 return backend_list[i];
101 }
102
103 drmFreeVersion(drm_version);
104 return NULL;
105}
106
107struct driver *drv_create(int fd)
108{
109 struct driver *drv;
110 int ret;
111
112 drv = (struct driver *) calloc(1, sizeof(*drv));
113
114 if (!drv)
115 return NULL;
116
117 drv->fd = fd;
118 drv->backend = drv_get_backend(fd);
119
Gurchetan Singh1a31e602016-10-06 10:58:00 -0700120 if (!drv->backend)
121 goto free_driver;
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700122
Gurchetan Singh27dd4702016-11-23 17:27:52 -0800123 if (pthread_mutex_init(&drv->driver_lock, NULL))
Gurchetan Singh1a31e602016-10-06 10:58:00 -0700124 goto free_driver;
Gurchetan Singh1647fbe2016-08-03 17:14:55 -0700125
126 drv->buffer_table = drmHashCreate();
Gurchetan Singh1a31e602016-10-06 10:58:00 -0700127 if (!drv->buffer_table)
128 goto free_lock;
129
130 drv->map_table = drmHashCreate();
131 if (!drv->map_table)
132 goto free_buffer_table;
Gurchetan Singh1647fbe2016-08-03 17:14:55 -0700133
Gurchetan Singh179687e2016-10-28 10:07:35 -0700134 LIST_INITHEAD(&drv->backend->combinations);
135
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700136 if (drv->backend->init) {
137 ret = drv->backend->init(drv);
Gurchetan Singh1a31e602016-10-06 10:58:00 -0700138 if (ret)
139 goto free_map_table;
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700140 }
141
142 return drv;
Gurchetan Singh1a31e602016-10-06 10:58:00 -0700143
144free_map_table:
145 drmHashDestroy(drv->map_table);
146free_buffer_table:
147 drmHashDestroy(drv->buffer_table);
148free_lock:
Gurchetan Singh27dd4702016-11-23 17:27:52 -0800149 pthread_mutex_destroy(&drv->driver_lock);
Gurchetan Singh1a31e602016-10-06 10:58:00 -0700150free_driver:
151 free(drv);
152 return NULL;
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700153}
154
155void drv_destroy(struct driver *drv)
156{
Gurchetan Singh27dd4702016-11-23 17:27:52 -0800157 pthread_mutex_lock(&drv->driver_lock);
Gurchetan Singh179687e2016-10-28 10:07:35 -0700158
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700159 if (drv->backend->close)
160 drv->backend->close(drv);
161
Gurchetan Singh1647fbe2016-08-03 17:14:55 -0700162 drmHashDestroy(drv->buffer_table);
Gurchetan Singh1a31e602016-10-06 10:58:00 -0700163 drmHashDestroy(drv->map_table);
Gurchetan Singh1647fbe2016-08-03 17:14:55 -0700164
Gurchetan Singh179687e2016-10-28 10:07:35 -0700165 list_for_each_entry_safe(struct combination_list_element, elem,
166 &drv->backend->combinations, link) {
167 LIST_DEL(&elem->link);
168 free(elem);
169 }
170
Gurchetan Singh27dd4702016-11-23 17:27:52 -0800171 pthread_mutex_unlock(&drv->driver_lock);
172 pthread_mutex_destroy(&drv->driver_lock);
Gurchetan Singh179687e2016-10-28 10:07:35 -0700173
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700174 free(drv);
175}
176
177int drv_get_fd(struct driver *drv)
178{
179 return drv->fd;
180}
181
182const char *
183drv_get_name(struct driver *drv)
184{
185 return drv->backend->name;
186}
187
Gurchetan Singh179687e2016-10-28 10:07:35 -0700188int drv_is_combination_supported(struct driver *drv, uint32_t format,
189 uint64_t usage, uint64_t modifier)
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700190{
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700191
Gurchetan Singh458976f2016-11-23 17:32:33 -0800192 if (format == DRM_FORMAT_NONE || usage == BO_USE_NONE)
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700193 return 0;
194
Gurchetan Singh179687e2016-10-28 10:07:35 -0700195 list_for_each_entry(struct combination_list_element, elem,
196 &drv->backend->combinations, link) {
197 if (format == elem->combination.format &&
198 usage == (elem->combination.usage & usage) &&
199 modifier == elem->combination.modifier)
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700200 return 1;
201 }
202
203 return 0;
204}
205
206struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height,
Gurchetan Singhf3b22da2016-11-21 10:46:38 -0800207 uint32_t format)
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700208{
209
210 struct bo *bo;
211 bo = (struct bo *) calloc(1, sizeof(*bo));
212
213 if (!bo)
214 return NULL;
215
216 bo->drv = drv;
217 bo->width = width;
218 bo->height = height;
219 bo->format = format;
220 bo->num_planes = drv_num_planes_from_format(format);
221
222 if (!bo->num_planes) {
223 free(bo);
224 return NULL;
225 }
226
227 return bo;
228}
229
230struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height,
Gurchetan Singhf3b22da2016-11-21 10:46:38 -0800231 uint32_t format, uint64_t flags)
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700232{
233 int ret;
Gurchetan Singh1647fbe2016-08-03 17:14:55 -0700234 size_t plane;
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700235 struct bo *bo;
236
237 bo = drv_bo_new(drv, width, height, format);
238
239 if (!bo)
240 return NULL;
241
242 ret = drv->backend->bo_create(bo, width, height, format, flags);
243
244 if (ret) {
245 free(bo);
246 return NULL;
247 }
248
Gurchetan Singh27dd4702016-11-23 17:27:52 -0800249 pthread_mutex_lock(&drv->driver_lock);
Gurchetan Singh1647fbe2016-08-03 17:14:55 -0700250
251 for (plane = 0; plane < bo->num_planes; plane++)
252 drv_increment_reference_count(drv, bo, plane);
253
Gurchetan Singh27dd4702016-11-23 17:27:52 -0800254 pthread_mutex_unlock(&drv->driver_lock);
Gurchetan Singh1647fbe2016-08-03 17:14:55 -0700255
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700256 return bo;
257}
258
Kristian H. Kristensenb1efbd82016-09-06 11:43:26 -0700259struct bo *drv_bo_create_with_modifiers(struct driver *drv,
260 uint32_t width, uint32_t height,
261 uint32_t format,
262 const uint64_t *modifiers, uint32_t count)
263{
264 int ret;
265 size_t plane;
266 struct bo *bo;
267
268 if (!drv->backend->bo_create_with_modifiers) {
269 errno = ENOENT;
270 return NULL;
271 }
272
273 bo = drv_bo_new(drv, width, height, format);
274
275 if (!bo)
276 return NULL;
277
278 ret = drv->backend->bo_create_with_modifiers(bo, width, height,
279 format, modifiers, count);
280
281 if (ret) {
282 free(bo);
283 return NULL;
284 }
285
286 pthread_mutex_lock(&drv->driver_lock);
287
288 for (plane = 0; plane < bo->num_planes; plane++)
289 drv_increment_reference_count(drv, bo, plane);
290
291 pthread_mutex_unlock(&drv->driver_lock);
292
293 return bo;
294}
295
296
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700297void drv_bo_destroy(struct bo *bo)
298{
Gurchetan Singh1647fbe2016-08-03 17:14:55 -0700299 size_t plane;
300 uintptr_t total = 0;
301 struct driver *drv = bo->drv;
302
Gurchetan Singh27dd4702016-11-23 17:27:52 -0800303 pthread_mutex_lock(&drv->driver_lock);
Gurchetan Singh1647fbe2016-08-03 17:14:55 -0700304
305 for (plane = 0; plane < bo->num_planes; plane++)
306 drv_decrement_reference_count(drv, bo, plane);
307
308 for (plane = 0; plane < bo->num_planes; plane++)
309 total += drv_get_reference_count(drv, bo, plane);
310
Gurchetan Singh27dd4702016-11-23 17:27:52 -0800311 pthread_mutex_unlock(&drv->driver_lock);
Gurchetan Singh1647fbe2016-08-03 17:14:55 -0700312
313 if (total == 0)
314 bo->drv->backend->bo_destroy(bo);
315
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700316 free(bo);
317}
318
319struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data)
320{
321 int ret;
Gurchetan Singhb72badb2016-08-19 16:26:46 -0700322 size_t plane;
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700323 struct bo *bo;
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700324
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700325 bo = drv_bo_new(drv, data->width, data->height, data->format);
326
Gurchetan Singhb72badb2016-08-19 16:26:46 -0700327 if (!bo)
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700328 return NULL;
Gurchetan Singhb72badb2016-08-19 16:26:46 -0700329
Gurchetan Singh71611d62017-01-03 16:49:56 -0800330 ret = drv->backend->bo_import(bo, data);
331 if (ret) {
332 free(bo);
333 return NULL;
334 }
335
Gurchetan Singhb72badb2016-08-19 16:26:46 -0700336 for (plane = 0; plane < bo->num_planes; plane++) {
Gurchetan Singhb72badb2016-08-19 16:26:46 -0700337 bo->strides[plane] = data->strides[plane];
338 bo->offsets[plane] = data->offsets[plane];
339 bo->sizes[plane] = data->sizes[plane];
Kristian H. Kristensen33459772016-09-16 11:14:16 -0700340 bo->format_modifiers[plane] = data->format_modifiers[plane];
Gurchetan Singh2e786ad2016-08-24 18:31:23 -0700341 bo->total_size += data->sizes[plane];
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700342 }
343
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700344 return bo;
345}
346
Gurchetan Singh1a31e602016-10-06 10:58:00 -0700347void *drv_bo_map(struct bo *bo, uint32_t x, uint32_t y, uint32_t width,
348 uint32_t height, uint32_t flags, void **map_data, size_t plane)
349{
350 void *ptr;
351 uint8_t *addr;
352 size_t offset;
353 struct map_info *data;
354
355 assert(width > 0);
356 assert(height > 0);
357 assert(x + width <= drv_bo_get_width(bo));
358 assert(y + height <= drv_bo_get_height(bo));
359
Gurchetan Singh27dd4702016-11-23 17:27:52 -0800360 pthread_mutex_lock(&bo->drv->driver_lock);
Gurchetan Singh1a31e602016-10-06 10:58:00 -0700361
362 if (!drmHashLookup(bo->drv->map_table, bo->handles[plane].u32, &ptr)) {
363 data = (struct map_info *) ptr;
364 data->refcount++;
365 goto success;
366 }
367
368 data = calloc(1, sizeof(*data));
369 addr = bo->drv->backend->bo_map(bo, data, plane);
370 if (addr == MAP_FAILED) {
371 *map_data = NULL;
372 free(data);
Gurchetan Singh27dd4702016-11-23 17:27:52 -0800373 pthread_mutex_unlock(&bo->drv->driver_lock);
Gurchetan Singh1a31e602016-10-06 10:58:00 -0700374 return MAP_FAILED;
375 }
376
377 data->refcount = 1;
378 data->addr = addr;
379 data->handle = bo->handles[plane].u32;
Gurchetan Singh7831b042017-02-13 10:29:32 -0800380 drmHashInsert(bo->drv->map_table, bo->handles[plane].u32,
Gurchetan Singh1a31e602016-10-06 10:58:00 -0700381 (void *) data);
382
383success:
384 *map_data = (void *) data;
385 offset = drv_bo_get_plane_stride(bo, plane) * y;
386 offset += drv_stride_from_format(bo->format, x, plane);
387 addr = (uint8_t *) data->addr;
388 addr += drv_bo_get_plane_offset(bo, plane) + offset;
Gurchetan Singh27dd4702016-11-23 17:27:52 -0800389 pthread_mutex_unlock(&bo->drv->driver_lock);
Gurchetan Singh1a31e602016-10-06 10:58:00 -0700390
391 return (void *) addr;
392}
393
394int drv_bo_unmap(struct bo *bo, void *map_data)
395{
396 struct map_info *data = map_data;
397 int ret = 0;
398
399 assert(data);
400 assert(data->refcount >= 0);
401
Gurchetan Singh27dd4702016-11-23 17:27:52 -0800402 pthread_mutex_lock(&bo->drv->driver_lock);
Gurchetan Singh1a31e602016-10-06 10:58:00 -0700403
404 if (!--data->refcount) {
Gurchetan Singh44d1fe42016-12-14 08:51:28 -0800405 if (bo->drv->backend->bo_unmap)
406 ret = bo->drv->backend->bo_unmap(bo, data);
407 else
408 ret = munmap(data->addr, data->length);
Gurchetan Singh1a31e602016-10-06 10:58:00 -0700409 drmHashDelete(bo->drv->map_table, data->handle);
410 free(data);
411 }
412
Gurchetan Singh27dd4702016-11-23 17:27:52 -0800413 pthread_mutex_unlock(&bo->drv->driver_lock);
Gurchetan Singh1a31e602016-10-06 10:58:00 -0700414
415 return ret;
416}
417
Gurchetan Singh46faf6b2016-08-05 14:40:07 -0700418uint32_t drv_bo_get_width(struct bo *bo)
419{
420 return bo->width;
421}
422
423uint32_t drv_bo_get_height(struct bo *bo)
424{
425 return bo->height;
426}
427
428uint32_t drv_bo_get_stride_or_tiling(struct bo *bo)
429{
430 return bo->tiling ? bo->tiling : drv_bo_get_plane_stride(bo, 0);
431}
432
433size_t drv_bo_get_num_planes(struct bo *bo)
434{
435 return bo->num_planes;
436}
437
438union bo_handle drv_bo_get_plane_handle(struct bo *bo, size_t plane)
439{
440 return bo->handles[plane];
441}
442
443#ifndef DRM_RDWR
444#define DRM_RDWR O_RDWR
445#endif
446
447int drv_bo_get_plane_fd(struct bo *bo, size_t plane)
448{
449
450 int ret, fd;
451 assert(plane < bo->num_planes);
452
453 ret = drmPrimeHandleToFD(bo->drv->fd, bo->handles[plane].u32,
454 DRM_CLOEXEC | DRM_RDWR, &fd);
455
456 return (ret) ? ret : fd;
457
458}
459
460uint32_t drv_bo_get_plane_offset(struct bo *bo, size_t plane)
461{
462 assert(plane < bo->num_planes);
463 return bo->offsets[plane];
464}
465
466uint32_t drv_bo_get_plane_size(struct bo *bo, size_t plane)
467{
468 assert(plane < bo->num_planes);
469 return bo->sizes[plane];
470}
471
472uint32_t drv_bo_get_plane_stride(struct bo *bo, size_t plane)
473{
474 assert(plane < bo->num_planes);
475 return bo->strides[plane];
476}
477
478uint64_t drv_bo_get_plane_format_modifier(struct bo *bo, size_t plane)
479{
480 assert(plane < bo->num_planes);
481 return bo->format_modifiers[plane];
482}
Gurchetan Singhbfba8c22016-08-16 17:57:10 -0700483
Gurchetan Singhf3b22da2016-11-21 10:46:38 -0800484uint32_t drv_bo_get_format(struct bo *bo)
Gurchetan Singh2e786ad2016-08-24 18:31:23 -0700485{
486 return bo->format;
487}
488
Gurchetan Singhf3b22da2016-11-21 10:46:38 -0800489uint32_t drv_resolve_format(struct driver *drv, uint32_t format)
Gurchetan Singhbfba8c22016-08-16 17:57:10 -0700490{
491 if (drv->backend->resolve_format)
492 return drv->backend->resolve_format(format);
493
494 return format;
495}
Gurchetan Singh2e786ad2016-08-24 18:31:23 -0700496
497/*
498 * This function returns the stride for a given format, width and plane.
499 */
500int drv_stride_from_format(uint32_t format, uint32_t width, size_t plane)
501{
Gurchetan Singh2a119342016-11-02 10:40:51 -0700502 int stride = width * DIV_ROUND_UP(drv_bpp_from_format(format, plane),
503 8);
Gurchetan Singh2e786ad2016-08-24 18:31:23 -0700504
505 /*
Gurchetan Singh2a119342016-11-02 10:40:51 -0700506 * Only downsample for certain multiplanar formats which have horizontal
507 * subsampling for chroma planes. Only formats supported by our drivers
508 * are listed here -- add more as needed.
Gurchetan Singh2e786ad2016-08-24 18:31:23 -0700509 */
510 if (plane != 0) {
511 switch (format) {
Gurchetan Singhf3b22da2016-11-21 10:46:38 -0800512 case DRM_FORMAT_NV12:
513 case DRM_FORMAT_YVU420:
Gurchetan Singh2e786ad2016-08-24 18:31:23 -0700514 stride = stride / 2;
515 break;
516 }
517 }
518
519 return stride;
520}
521
Gurchetan Singh2a119342016-11-02 10:40:51 -0700522size_t drv_num_planes_from_format(uint32_t format)
523{
524 switch (format) {
Gurchetan Singhe8ab0a52016-11-21 11:36:31 -0800525 case DRM_FORMAT_ABGR1555:
526 case DRM_FORMAT_ABGR2101010:
527 case DRM_FORMAT_ABGR4444:
528 case DRM_FORMAT_ABGR8888:
529 case DRM_FORMAT_ARGB1555:
530 case DRM_FORMAT_ARGB2101010:
531 case DRM_FORMAT_ARGB4444:
532 case DRM_FORMAT_ARGB8888:
533 case DRM_FORMAT_AYUV:
534 case DRM_FORMAT_BGR233:
535 case DRM_FORMAT_BGR565:
536 case DRM_FORMAT_BGR888:
537 case DRM_FORMAT_BGRA1010102:
538 case DRM_FORMAT_BGRA4444:
539 case DRM_FORMAT_BGRA5551:
540 case DRM_FORMAT_BGRA8888:
541 case DRM_FORMAT_BGRX1010102:
542 case DRM_FORMAT_BGRX4444:
543 case DRM_FORMAT_BGRX5551:
544 case DRM_FORMAT_BGRX8888:
Gurchetan Singhf3b22da2016-11-21 10:46:38 -0800545 case DRM_FORMAT_C8:
Gurchetan Singhe8ab0a52016-11-21 11:36:31 -0800546 case DRM_FORMAT_GR88:
Gurchetan Singhf3b22da2016-11-21 10:46:38 -0800547 case DRM_FORMAT_R8:
548 case DRM_FORMAT_RG88:
Gurchetan Singhf3b22da2016-11-21 10:46:38 -0800549 case DRM_FORMAT_RGB332:
Gurchetan Singhf3b22da2016-11-21 10:46:38 -0800550 case DRM_FORMAT_RGB565:
Gurchetan Singhe8ab0a52016-11-21 11:36:31 -0800551 case DRM_FORMAT_RGB888:
552 case DRM_FORMAT_RGBA1010102:
553 case DRM_FORMAT_RGBA4444:
554 case DRM_FORMAT_RGBA5551:
555 case DRM_FORMAT_RGBA8888:
556 case DRM_FORMAT_RGBX1010102:
557 case DRM_FORMAT_RGBX4444:
558 case DRM_FORMAT_RGBX5551:
559 case DRM_FORMAT_RGBX8888:
Gurchetan Singhf3b22da2016-11-21 10:46:38 -0800560 case DRM_FORMAT_UYVY:
561 case DRM_FORMAT_VYUY:
Gurchetan Singhe8ab0a52016-11-21 11:36:31 -0800562 case DRM_FORMAT_XBGR1555:
Gurchetan Singhf3b22da2016-11-21 10:46:38 -0800563 case DRM_FORMAT_XBGR2101010:
Gurchetan Singhe8ab0a52016-11-21 11:36:31 -0800564 case DRM_FORMAT_XBGR4444:
565 case DRM_FORMAT_XBGR8888:
566 case DRM_FORMAT_XRGB1555:
567 case DRM_FORMAT_XRGB2101010:
568 case DRM_FORMAT_XRGB4444:
569 case DRM_FORMAT_XRGB8888:
570 case DRM_FORMAT_YUYV:
571 case DRM_FORMAT_YVYU:
Gurchetan Singh2a119342016-11-02 10:40:51 -0700572 return 1;
Gurchetan Singhf3b22da2016-11-21 10:46:38 -0800573 case DRM_FORMAT_NV12:
Gurchetan Singh2a119342016-11-02 10:40:51 -0700574 return 2;
Gurchetan Singhf3b22da2016-11-21 10:46:38 -0800575 case DRM_FORMAT_YVU420:
Gurchetan Singh2a119342016-11-02 10:40:51 -0700576 return 3;
577 }
578
579 fprintf(stderr, "drv: UNKNOWN FORMAT %d\n", format);
580 return 0;
581}
582
Gurchetan Singhf3b22da2016-11-21 10:46:38 -0800583uint32_t drv_size_from_format(uint32_t format, uint32_t stride,
Gurchetan Singh2a119342016-11-02 10:40:51 -0700584 uint32_t height, size_t plane)
585{
586 assert(plane < drv_num_planes_from_format(format));
587 uint32_t vertical_subsampling;
588
589 switch (format) {
Gurchetan Singhf3b22da2016-11-21 10:46:38 -0800590 case DRM_FORMAT_NV12:
Gurchetan Singhe8ab0a52016-11-21 11:36:31 -0800591 case DRM_FORMAT_YVU420:
Gurchetan Singh2a119342016-11-02 10:40:51 -0700592 vertical_subsampling = (plane == 0) ? 1 : 2;
593 break;
594 default:
595 vertical_subsampling = 1;
596 }
597
598 return stride * DIV_ROUND_UP(height, vertical_subsampling);
599}
600
Gurchetan Singh2e786ad2016-08-24 18:31:23 -0700601uint32_t drv_num_buffers_per_bo(struct bo *bo)
602{
603 uint32_t count = 0;
604 size_t plane, p;
605
606 for (plane = 0; plane < bo->num_planes; plane++) {
607 for (p = 0; p < plane; p++)
608 if (bo->handles[p].u32 == bo->handles[plane].u32)
609 break;
610 if (p == plane)
611 count++;
612 }
613
614 return count;
615}