return stride;
}
+/*
+ * This function fills in the buffer object given driver aligned dimensions
+ * and a format. This function assumes there is just one kernel buffer per
+ * buffer object.
+ */
+int drv_bo_from_format(struct bo *bo, uint32_t width, uint32_t height,
+ drv_format_t format)
+{
+
+ switch (format) {
+ case DRV_FORMAT_YVU420:
+ bo->strides[0] = drv_stride_from_format(format, width, 0);
+ bo->strides[1] = drv_stride_from_format(format, width, 1);
+ bo->strides[2] = drv_stride_from_format(format, width, 2);
+ bo->sizes[0] = height * bo->strides[0];
+ bo->sizes[1] = bo->sizes[2] = (height / 2) * bo->strides[1];
+ bo->offsets[0] = 0;
+ bo->offsets[1] = bo->sizes[0];
+ bo->offsets[2] = bo->offsets[1] + bo->sizes[1];
+ break;
+ case DRV_FORMAT_NV12:
+ bo->strides[0] = drv_stride_from_format(format, width, 0);
+ bo->strides[1] = drv_stride_from_format(format, width, 1);
+ bo->sizes[0] = height * bo->strides[0];
+ bo->sizes[1] = height * bo->strides[1] / 2;
+ bo->offsets[0] = 0;
+ bo->offsets[1] = height * bo->strides[0];
+ break;
+ default:
+ bo->strides[0] = drv_stride_from_format(format, width, 0);
+ bo->sizes[0] = height * bo->strides[0];
+ bo->offsets[0] = 0;
+ }
+
+ return 0;
+}
+
int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height,
uint32_t format, uint32_t flags)
{
size_t drv_num_planes_from_format(uint32_t format);
int drv_bpp_from_format(uint32_t format, size_t plane);
int drv_stride_from_format(uint32_t format, uint32_t width, size_t plane);
+int drv_bo_from_format(struct bo *bo, uint32_t width, uint32_t height,
+ drv_format_t format);
int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height,
uint32_t format, uint32_t flags);
int drv_dumb_bo_destroy(struct bo *bo);
struct drm_i915_gem_create gem_create;
struct drm_i915_gem_set_tiling gem_set_tiling;
uint32_t tiling_mode = I915_TILING_NONE;
- size_t size, plane;
+ size_t plane;
int ret;
if (flags & (DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR |
i915_align_dimensions(drv, tiling_mode, &width, &height, bpp);
- switch (format) {
- case DRV_FORMAT_YVU420:
- bo->strides[0] = drv_stride_from_format(format, width, 0);
- bo->strides[1] = bo->strides[2] = drv_stride_from_format(format, width, 1);
- bo->sizes[0] = height * bo->strides[0];
- bo->sizes[1] = bo->sizes[2] = (height / 2) * bo->strides[1];
- bo->offsets[0] = 0;
- bo->offsets[1] = bo->sizes[0];
- bo->offsets[2] = bo->offsets[1] + bo->sizes[1];
- break;
- default:
- bo->strides[0] = drv_stride_from_format(format, width, 0);
- bo->sizes[0] = height * bo->strides[0];
- bo->offsets[0] = 0;
- }
+ drv_bo_from_format(bo, width, height, format);
if (!i915_verify_dimensions(drv, bo->strides[0], height))
return EINVAL;
- size = bo->offsets[bo->num_planes - 1] + bo->sizes[bo->num_planes - 1];
memset(&gem_create, 0, sizeof(gem_create));
- gem_create.size = size;
+ gem_create.size = bo->offsets[bo->num_planes - 1] +
+ bo->sizes[bo->num_planes - 1];
ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create);
if (ret) {
fprintf(stderr, "drv: DRM_IOCTL_I915_GEM_CREATE failed "
- "(size=%zu)\n", size);
+ "(size=%llu)\n", gem_create.size);
return ret;
}
bo->drv->fd, gem_map.offset);
}
-drv_format_t i915_resolve_format(drv_format_t format)
+static drv_format_t i915_resolve_format(drv_format_t format)
{
switch (format) {
case DRV_FORMAT_FLEX_IMPLEMENTATION_DEFINED:
static int mediatek_bo_create(struct bo *bo, uint32_t width, uint32_t height,
uint32_t format, uint32_t flags)
{
- size_t size;
- struct drm_mtk_gem_create gem_create;
int ret;
+ size_t plane;
+ struct drm_mtk_gem_create gem_create;
- bo->strides[0] = drv_stride_from_format(format, width, 0);
- size = height * bo->strides[0];
+ drv_bo_from_format(bo, width, height, format);
memset(&gem_create, 0, sizeof(gem_create));
- gem_create.size = size;
+ gem_create.size = bo->offsets[bo->num_planes - 1] +
+ bo->sizes[bo->num_planes - 1];
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MTK_GEM_CREATE, &gem_create);
if (ret) {
fprintf(stderr, "drv: DRM_IOCTL_MTK_GEM_CREATE failed "
- "(size=%zu)\n", size);
+ "(size=%llu)\n", gem_create.size);
return ret;
}
- bo->handles[0].u32 = gem_create.handle;
- bo->sizes[0] = size;
- bo->offsets[0] = 0;
+ for (plane = 0; plane < bo->num_planes; plane++)
+ bo->handles[plane].u32 = gem_create.handle;
return 0;
}
bo->drv->fd, gem_map.offset);
}
+static drv_format_t mediatek_resolve_format(drv_format_t format)
+{
+ switch (format) {
+ case DRV_FORMAT_FLEX_IMPLEMENTATION_DEFINED:
+ /*HACK: See b/28671744 */
+ return DRV_FORMAT_XBGR8888;
+ case DRV_FORMAT_FLEX_YCbCr_420_888:
+ return DRV_FORMAT_YVU420;
+ default:
+ return format;
+ }
+}
+
const struct backend backend_mediatek =
{
.name = "mediatek",
.bo_create = mediatek_bo_create,
.bo_destroy = drv_gem_bo_destroy,
.bo_map = mediatek_bo_map,
+ .resolve_format = mediatek_resolve_format,
.format_list = {
{DRV_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR |
DRV_BO_USE_RENDERING | DRV_BO_USE_HW_TEXTURE |
{DRV_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR |
DRV_BO_USE_LINEAR | DRV_BO_USE_SW_READ_OFTEN |
DRV_BO_USE_SW_WRITE_OFTEN},
+ {DRV_FORMAT_YVU420, DRV_BO_USE_LINEAR | DRV_BO_USE_SW_READ_OFTEN |
+ DRV_BO_USE_SW_WRITE_OFTEN},
}
};
static int rockchip_bo_create(struct bo *bo, uint32_t width, uint32_t height,
uint32_t format, uint32_t flags)
{
+ int ret;
size_t plane;
+ struct drm_rockchip_gem_create gem_create;
- switch (format) {
- case DRV_FORMAT_NV12:
- width = ALIGN(width, 4);
- height = ALIGN(height, 4);
- bo->strides[0] = bo->strides[1] = width;
- bo->sizes[0] = height * bo->strides[0];
- bo->sizes[1] = height * bo->strides[1] / 2;
- bo->offsets[0] = 0;
- bo->offsets[1] = height * bo->strides[0];
- break;
- case DRV_FORMAT_XRGB8888:
- case DRV_FORMAT_XBGR8888:
- case DRV_FORMAT_ARGB8888:
- case DRV_FORMAT_ABGR8888:
- bo->strides[0] = drv_stride_from_format(format, width, 0);
- bo->sizes[0] = height * bo->strides[0];
- bo->offsets[0] = 0;
- break;
- default:
- fprintf(stderr, "drv: rockchip: unsupported format %4.4s\n",
- (char*)&format);
- assert(0);
- return -EINVAL;
+ if (format == DRV_FORMAT_NV12) {
+ width = ALIGN(width, 4);
+ height = ALIGN(height, 4);
}
- int ret;
- size_t size = 0;
-
- for (plane = 0; plane < bo->num_planes; plane++)
- size += bo->sizes[plane];
-
- struct drm_rockchip_gem_create gem_create;
+ drv_bo_from_format(bo, width, height, format);
memset(&gem_create, 0, sizeof(gem_create));
- gem_create.size = size;
+ gem_create.size = bo->offsets[bo->num_planes - 1] +
+ bo->sizes[bo->num_planes - 1];
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_ROCKCHIP_GEM_CREATE,
&gem_create);
if (ret) {
fprintf(stderr, "drv: DRM_IOCTL_ROCKCHIP_GEM_CREATE failed "
- "(size=%zu)\n", size);
- }
- else {
- for (plane = 0; plane < bo->num_planes; plane++)
- bo->handles[plane].u32 = gem_create.handle;
+ "(size=%llu)\n", gem_create.size);
+ return ret;
}
- return ret;
+ for (plane = 0; plane < bo->num_planes; plane++)
+ bo->handles[plane].u32 = gem_create.handle;
+
+ return 0;
}
static void *rockchip_bo_map(struct bo *bo)
bo->drv->fd, gem_map.offset);
}
-drv_format_t rockchip_resolve_format(drv_format_t format)
+static drv_format_t rockchip_resolve_format(drv_format_t format)
{
switch (format) {
case DRV_FORMAT_FLEX_IMPLEMENTATION_DEFINED:
DRV_BO_USE_SW_WRITE_RARELY},
{DRV_FORMAT_NV12, DRV_BO_USE_SCANOUT | DRV_BO_USE_LINEAR |
DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
+ {DRV_FORMAT_YVU420, DRV_BO_USE_LINEAR | DRV_BO_USE_SW_READ_OFTEN |
+ DRV_BO_USE_SW_WRITE_OFTEN},
}
};