OSDN Git Service

minigbm: run presubmit.sh and add OWNERS file
[android-x86/external-minigbm.git] / virtio_gpu.c
index 5200b3d..8abeb91 100644 (file)
@@ -30,7 +30,8 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA
                                                  DRM_FORMAT_XRGB8888 };
 
 static const uint32_t dumb_texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420,
-                                                       DRM_FORMAT_YVU420_ANDROID };
+                                                       DRM_FORMAT_YVU420_ANDROID,
+                                                       DRM_FORMAT_NV12 };
 
 static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_RG88 };
 
@@ -63,16 +64,37 @@ static uint32_t translate_format(uint32_t drm_fourcc, uint32_t plane)
 static int virtio_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format,
                                 uint64_t use_flags)
 {
-       width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE);
-       height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE);
-
-       /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */
-       if (bo->format == DRM_FORMAT_YVU420_ANDROID)
-               height = bo->height;
+       if (bo->format != DRM_FORMAT_R8) {
+               width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE);
+               height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE);
+       }
 
        return drv_dumb_bo_create(bo, width, height, format, use_flags);
 }
 
+static inline void handle_flag(uint64_t *flag, uint64_t check_flag, uint32_t *bind,
+                              uint32_t virgl_bind)
+{
+       if ((*flag) & check_flag) {
+               (*flag) &= ~check_flag;
+               (*bind) |= virgl_bind;
+       }
+}
+
+static uint32_t use_flags_to_bind(uint64_t use_flags)
+{
+       uint32_t bind = 0;
+
+       handle_flag(&use_flags, BO_USE_TEXTURE, &bind, VIRGL_BIND_SAMPLER_VIEW);
+       handle_flag(&use_flags, BO_USE_RENDERING, &bind, VIRGL_BIND_RENDER_TARGET);
+       handle_flag(&use_flags, BO_USE_SCANOUT, &bind, VIRGL_BIND_SCANOUT);
+       // TODO (b/12983436): handle other use flags.
+       if (use_flags) {
+               drv_log("Unhandled bo use flag: %llx\n", (unsigned long long)use_flags);
+       }
+       return bind;
+}
+
 static int virtio_virgl_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format,
                                  uint64_t use_flags)
 {
@@ -80,6 +102,7 @@ static int virtio_virgl_bo_create(struct bo *bo, uint32_t width, uint32_t height
        ssize_t plane;
        ssize_t num_planes = drv_num_planes_from_format(format);
        uint32_t stride0;
+       uint32_t bind = use_flags_to_bind(use_flags);
 
        for (plane = 0; plane < num_planes; plane++) {
                uint32_t stride = drv_stride_from_format(format, width, plane);
@@ -98,7 +121,7 @@ static int virtio_virgl_bo_create(struct bo *bo, uint32_t width, uint32_t height
                 */
                res_create.target = PIPE_TEXTURE_2D;
                res_create.format = res_format;
-               res_create.bind = VIRGL_BIND_RENDER_TARGET;
+               res_create.bind = bind;
                res_create.width = width;
                res_create.height = height;
                res_create.depth = 1;
@@ -112,6 +135,7 @@ static int virtio_virgl_bo_create(struct bo *bo, uint32_t width, uint32_t height
                if (ret) {
                        drv_log("DRM_IOCTL_VIRTGPU_RESOURCE_CREATE failed with %s\n",
                                strerror(errno));
+                       ret = -errno;
                        goto fail;
                }
 
@@ -175,8 +199,10 @@ static int virtio_gpu_init(struct driver *drv)
                priv->has_3d = 0;
        }
 
+       /* This doesn't mean host can scanout everything, it just means host
+        * hypervisor can show it. */
        drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats),
-                            &LINEAR_METADATA, BO_USE_RENDER_MASK);
+                            &LINEAR_METADATA, BO_USE_RENDER_MASK | BO_USE_SCANOUT);
 
        if (priv->has_3d)
                drv_add_combinations(drv, texture_source_formats,
@@ -187,6 +213,14 @@ static int virtio_gpu_init(struct driver *drv)
                                     ARRAY_SIZE(dumb_texture_source_formats), &LINEAR_METADATA,
                                     BO_USE_TEXTURE_MASK);
 
+       /* Android CTS tests require this. */
+       drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK);
+
+       drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA,
+                              BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
+       drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA,
+                              BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
+
        return drv_modify_linear_combinations(drv);
 }
 
@@ -244,7 +278,7 @@ static int virtio_gpu_bo_invalidate(struct bo *bo, struct mapping *mapping)
        ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST, &xfer);
        if (ret) {
                drv_log("DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST failed with %s\n", strerror(errno));
-               return ret;
+               return -errno;
        }
 
        return 0;
@@ -273,7 +307,7 @@ static int virtio_gpu_bo_flush(struct bo *bo, struct mapping *mapping)
        ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST, &xfer);
        if (ret) {
                drv_log("DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST failed with %s\n", strerror(errno));
-               return ret;
+               return -errno;
        }
 
        return 0;
@@ -283,6 +317,9 @@ static uint32_t virtio_gpu_resolve_format(uint32_t format, uint64_t use_flags)
 {
        switch (format) {
        case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED:
+               /* Camera subsystem requires NV12. */
+               if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE))
+                       return DRM_FORMAT_NV12;
                /*HACK: See b/28671744 */
                return DRM_FORMAT_XBGR8888;
        case DRM_FORMAT_FLEX_YCbCr_420_888: