st/va/postproc: use progressive target buffer for scaling
authorLeo Liu <leo.liu@amd.com>
Tue, 19 Sep 2017 17:00:15 +0000 (13:00 -0400)
committerLeo Liu <leo.liu@amd.com>
Mon, 25 Sep 2017 13:42:14 +0000 (09:42 -0400)
Scaling between interlaced buffers, esp. for scale-up, because
blit will scale up top filed and bottom field separately. it'll
result in the weaving for these buffer with lack of accuracy.
So use shader deint for the case.

Acked-by: Christian König <christian.koenig@amd.com>
src/gallium/state_trackers/va/postproc.c

index 44491263167bb2aee78f3e3e9a60d40840feb914..d3eafe9b53b85c36ab9f1dc04917e6b4887935eb 100644 (file)
@@ -118,15 +118,33 @@ static VAStatus vlVaPostProcBlit(vlVaDriver *drv, vlVaContext *context,
    struct pipe_surface **dst_surfaces;
    struct u_rect src_rect;
    struct u_rect dst_rect;
+   bool scale = false;
    unsigned i;
 
    if (src->interlaced != dst->interlaced && dst->interlaced)
       return VA_STATUS_ERROR_INVALID_SURFACE;
 
+   if ((src->width != dst->width || src->height != dst->height) &&
+       (src->interlaced && dst->interlaced))
+      scale = true;
+
    src_surfaces = src->get_surfaces(src);
    if (!src_surfaces || !src_surfaces[0])
       return VA_STATUS_ERROR_INVALID_SURFACE;
 
+   if (scale) {
+      vlVaSurface *surf;
+
+      surf = handle_table_get(drv->htab, context->target_id);
+      surf->templat.interlaced = false;
+      dst->destroy(dst);
+
+      if (vlVaHandleSurfaceAllocate(drv, surf, &surf->templat) != VA_STATUS_SUCCESS)
+         return VA_STATUS_ERROR_ALLOCATION_FAILED;
+
+      dst = context->target = surf->buffer;
+   }
+
    dst_surfaces = dst->get_surfaces(dst);
    if (!dst_surfaces || !dst_surfaces[0])
       return VA_STATUS_ERROR_INVALID_SURFACE;