generic-poky/meta-emenlow/packages/libva/libva-0.31.0/038_g45_vaPutSurface_clipre...

532 lines
19 KiB
Diff

From 90de12a47e26ccc0b4cc8189c76991609481870d Mon Sep 17 00:00:00 2001
From: Gwenole Beauchesne <gbeauchesne@splitted-desktop.com>
Date: Wed, 4 Nov 2009 17:34:53 +0000
Subject: [PATCH] [G45] Handle cliprects in vaPutSurface().
---
i965_drv_video/i965_drv_video.c | 39 ++++--
i965_drv_video/i965_render.c | 284 +++++++++++++++++++--------------------
i965_drv_video/i965_render.h | 30 ++---
3 files changed, 176 insertions(+), 177 deletions(-)
diff --git a/i965_drv_video/i965_drv_video.c b/i965_drv_video/i965_drv_video.c
index e8f638c..20d6bab 100644
--- a/i965_drv_video/i965_drv_video.c
+++ b/i965_drv_video/i965_drv_video.c
@@ -1507,13 +1507,23 @@ i965_PutSurface(VADriverContextP ctx,
union dri_buffer *buffer;
struct intel_region *dest_region;
struct object_surface *obj_surface;
- int ret;
+ int ret;
uint32_t name;
+ VARectangle src_rect, dst_rect;
Bool new_region = False;
+
/* Currently don't support DRI1 */
if (dri_state->driConnectedFlag != VA_DRI2)
return VA_STATUS_ERROR_UNKNOWN;
+ /* XXX: we currently only support up to 64 cliprects */
+ if (number_cliprects > MAX_CLIP_RECTS)
+ return VA_STATUS_ERROR_OPERATION_FAILED;
+
+ obj_surface = SURFACE(surface);
+ if (!obj_surface)
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+
dri_drawable = dri_get_drawable(ctx, draw);
assert(dri_drawable);
@@ -1552,17 +1562,24 @@ i965_PutSurface(VADriverContextP ctx,
assert(ret == 0);
}
- i965_render_put_surface(ctx, surface,
- srcx, srcy, srcw, srch,
- destx, desty, destw, desth);
- obj_surface = SURFACE(surface);
- if(obj_surface->subpic != VA_INVALID_ID) {
- i965_render_put_subpic(ctx, surface,
- srcx, srcy, srcw, srch,
- destx, desty, destw, desth);
- }
- dri_swap_buffer(ctx, dri_drawable);
+ src_rect.x = srcx;
+ src_rect.y = srcy;
+ src_rect.width = srcw;
+ src_rect.height = srch;
+
+ dst_rect.x = destx;
+ dst_rect.y = desty;
+ dst_rect.width = destw;
+ dst_rect.height = desth;
+ i965_render_put_surface(ctx, surface, &src_rect, &dst_rect,
+ cliprects, number_cliprects);
+
+ if (obj_surface->subpic != VA_INVALID_ID)
+ i965_render_put_subpic(ctx, surface, &src_rect, &dst_rect,
+ cliprects, number_cliprects);
+
+ dri_swap_buffer(ctx, dri_drawable);
return VA_STATUS_SUCCESS;
}
diff --git a/i965_drv_video/i965_render.c b/i965_drv_video/i965_render.c
index 0476087..d7cd8fe 100644
--- a/i965_drv_video/i965_render.c
+++ b/i965_drv_video/i965_render.c
@@ -787,13 +787,81 @@ i965_render_binding_table(VADriverContextP ctx)
dri_bo_unmap(render_state->wm.binding_table);
}
-static void
+static unsigned int
+i965_render_do_upload_vertex(VADriverContextP ctx,
+ unsigned int width,
+ unsigned int height,
+ const VARectangle *src_rect,
+ const VARectangle *dst_rect,
+ const VARectangle *cliprects,
+ unsigned int num_cliprects)
+{
+ struct i965_driver_data *i965 = i965_driver_data(ctx);
+ struct i965_render_state *render_state = &i965->render_state;
+ struct intel_region *dest_region = render_state->draw_region;
+ float *vb, tx1, tx2, ty1, ty2;
+ int x1, x2, y1, y2;
+ unsigned int i, n;
+
+ if (!cliprects || num_cliprects == 0) {
+ cliprects = dst_rect;
+ num_cliprects = 1;
+ }
+
+ dri_bo_map(render_state->vb.vertex_buffer, 1);
+ assert(render_state->vb.vertex_buffer->virtual);
+ vb = render_state->vb.vertex_buffer->virtual;
+
+ for (n = 0, i = 0; i < num_cliprects; i++) {
+ x1 = dest_region->x + cliprects[i].x;
+ y1 = dest_region->y + cliprects[i].y;
+ x2 = x1 + cliprects[i].width;
+ y2 = y1 + cliprects[i].height;
+ x1 = MAX(x1, dst_rect->x);
+ y1 = MAX(y1, dst_rect->y);
+ x2 = MIN(x2, dst_rect->x + dst_rect->width);
+ y2 = MIN(y2, dst_rect->y + dst_rect->height);
+
+ if (x2 <= x1 || y2 <= y1)
+ continue;
+
+ const float sx1 = (float)(x1 - dst_rect->x) / (float)dst_rect->width;
+ const float sy1 = (float)(y1 - dst_rect->y) / (float)dst_rect->height;
+ const float sx2 = (float)(x2 - dst_rect->x) / (float)dst_rect->width;
+ const float sy2 = (float)(y2 - dst_rect->y) / (float)dst_rect->height;
+ tx1 = ((float)src_rect->x + sx1 * (float)src_rect->width) / width;
+ ty1 = ((float)src_rect->y + sy1 * (float)src_rect->height) / height;
+ tx2 = ((float)src_rect->x + sx2 * (float)src_rect->width) / width;
+ ty2 = ((float)src_rect->y + sy2 * (float)src_rect->height) / height;
+
+ vb[n++] = tx2;
+ vb[n++] = ty2;
+ vb[n++] = x2;
+ vb[n++] = y2;
+
+ vb[n++] = tx1;
+ vb[n++] = ty2;
+ vb[n++] = x1;
+ vb[n++] = y2;
+
+ vb[n++] = tx1;
+ vb[n++] = ty1;
+ vb[n++] = x1;
+ vb[n++] = y1;
+ }
+
+ dri_bo_unmap(render_state->vb.vertex_buffer);
+ return n / 12;
+}
+
+static unsigned int
i965_subpic_render_upload_vertex(VADriverContextP ctx,
VASurfaceID surface,
- const VARectangle *output_rect)
-{
+ const VARectangle *output_rect,
+ const VARectangle *cliprects,
+ unsigned int num_cliprects)
+{
struct i965_driver_data *i965 = i965_driver_data(ctx);
- struct i965_render_state *render_state = &i965->render_state;
struct object_surface *obj_surface = SURFACE(surface);
struct object_subpic *obj_subpic = SUBPIC(obj_surface->subpic);
@@ -803,8 +871,6 @@ i965_subpic_render_upload_vertex(VADriverContextP ctx,
const float ssy = (float)output_rect->height / (float)obj_surface->height;
const float sx = psx * ssx;
const float sy = psy * ssy;
- float *vb, tx1, tx2, ty1, ty2, x1, x2, y1, y2;
- int i = 0;
VARectangle dst_rect;
dst_rect.x = output_rect->x + sx * (float)obj_subpic->dst_rect.x;
@@ -812,106 +878,38 @@ i965_subpic_render_upload_vertex(VADriverContextP ctx,
dst_rect.width = sx * (float)obj_subpic->dst_rect.width;
dst_rect.height = sy * (float)obj_subpic->dst_rect.height;
- dri_bo_map(render_state->vb.vertex_buffer, 1);
- assert(render_state->vb.vertex_buffer->virtual);
- vb = render_state->vb.vertex_buffer->virtual;
-
- tx1 = (float)obj_subpic->src_rect.x / (float)obj_subpic->width;
- ty1 = (float)obj_subpic->src_rect.y / (float)obj_subpic->height;
- tx2 = (float)(obj_subpic->src_rect.x + obj_subpic->src_rect.width) / (float)obj_subpic->width;
- ty2 = (float)(obj_subpic->src_rect.y + obj_subpic->src_rect.height) / (float)obj_subpic->height;
-
- x1 = (float)dst_rect.x;
- y1 = (float)dst_rect.y;
- x2 = (float)(dst_rect.x + dst_rect.width);
- y2 = (float)(dst_rect.y + dst_rect.height);
-
- vb[i++] = tx2;
- vb[i++] = ty2;
- vb[i++] = x2;
- vb[i++] = y2;
-
- vb[i++] = tx1;
- vb[i++] = ty2;
- vb[i++] = x1;
- vb[i++] = y2;
-
- vb[i++] = tx1;
- vb[i++] = ty1;
- vb[i++] = x1;
- vb[i++] = y1;
- dri_bo_unmap(render_state->vb.vertex_buffer);
+ return i965_render_do_upload_vertex(ctx,
+ obj_subpic->width, obj_subpic->height,
+ &obj_subpic->src_rect, &dst_rect,
+ cliprects, num_cliprects);
}
-static void
+static unsigned int
i965_render_upload_vertex(VADriverContextP ctx,
VASurfaceID surface,
- short srcx,
- short srcy,
- unsigned short srcw,
- unsigned short srch,
- short destx,
- short desty,
- unsigned short destw,
- unsigned short desth)
+ const VARectangle *src_rect,
+ const VARectangle *dst_rect,
+ const VARectangle *cliprects,
+ unsigned int num_cliprects)
{
struct i965_driver_data *i965 = i965_driver_data(ctx);
- struct i965_render_state *render_state = &i965->render_state;
- struct intel_region *dest_region = render_state->draw_region;
- struct object_surface *obj_surface;
- float *vb;
-
- float u1, v1, u2, v2;
- int i, width, height;
- int box_x1 = dest_region->x + destx;
- int box_y1 = dest_region->y + desty;
- int box_x2 = box_x1 + destw;
- int box_y2 = box_y1 + desth;
-
- obj_surface = SURFACE(surface);
- assert(surface);
- width = obj_surface->width;
- height = obj_surface->height;
-
- u1 = (float)srcx / width;
- v1 = (float)srcy / height;
- u2 = (float)(srcx + srcw) / width;
- v2 = (float)(srcy + srch) / height;
-
- dri_bo_map(render_state->vb.vertex_buffer, 1);
- assert(render_state->vb.vertex_buffer->virtual);
- vb = render_state->vb.vertex_buffer->virtual;
-
- i = 0;
- vb[i++] = u2;
- vb[i++] = v2;
- vb[i++] = (float)box_x2;
- vb[i++] = (float)box_y2;
-
- vb[i++] = u1;
- vb[i++] = v2;
- vb[i++] = (float)box_x1;
- vb[i++] = (float)box_y2;
-
- vb[i++] = u1;
- vb[i++] = v1;
- vb[i++] = (float)box_x1;
- vb[i++] = (float)box_y1;
+ struct object_surface *obj_surface = SURFACE(surface);
+ assert(obj_surface);
- dri_bo_unmap(render_state->vb.vertex_buffer);
+ return i965_render_do_upload_vertex(ctx,
+ obj_surface->width, obj_surface->height,
+ src_rect,
+ dst_rect,
+ cliprects, num_cliprects);
}
-static void
+static unsigned int
i965_surface_render_state_setup(VADriverContextP ctx,
- VASurfaceID surface,
- short srcx,
- short srcy,
- unsigned short srcw,
- unsigned short srch,
- short destx,
- short desty,
- unsigned short destw,
- unsigned short desth)
+ VASurfaceID surface,
+ const VARectangle *src_rect,
+ const VARectangle *dst_rect,
+ const VARectangle *cliprects,
+ unsigned int num_cliprects)
{
i965_render_vs_unit(ctx);
i965_render_sf_unit(ctx);
@@ -922,21 +920,17 @@ i965_surface_render_state_setup(VADriverContextP ctx,
i965_render_cc_viewport(ctx);
i965_render_cc_unit(ctx);
i965_render_binding_table(ctx);
- i965_render_upload_vertex(ctx, surface,
- srcx, srcy, srcw, srch,
- destx, desty, destw, desth);
+ return i965_render_upload_vertex(ctx, surface, src_rect, dst_rect,
+ cliprects, num_cliprects);
}
-static void
+
+static unsigned int
i965_subpic_render_state_setup(VADriverContextP ctx,
- VASurfaceID surface,
- short srcx,
- short srcy,
- unsigned short srcw,
- unsigned short srch,
- short destx,
- short desty,
- unsigned short destw,
- unsigned short desth)
+ VASurfaceID surface,
+ const VARectangle *src_rect,
+ const VARectangle *dst_rect,
+ const VARectangle *cliprects,
+ unsigned int num_cliprects)
{
i965_render_vs_unit(ctx);
i965_render_sf_unit(ctx);
@@ -947,16 +941,10 @@ i965_subpic_render_state_setup(VADriverContextP ctx,
i965_render_cc_viewport(ctx);
i965_subpic_render_cc_unit(ctx);
i965_render_binding_table(ctx);
-
- VARectangle output_rect;
- output_rect.x = destx;
- output_rect.y = desty;
- output_rect.width = destw;
- output_rect.height = desth;
- i965_subpic_render_upload_vertex(ctx, surface, &output_rect);
+ return i965_subpic_render_upload_vertex(ctx, surface, dst_rect,
+ cliprects, num_cliprects);
}
-
static void
i965_render_pipeline_select(VADriverContextP ctx)
{
@@ -1192,7 +1180,7 @@ i965_render_upload_image_palette(
}
static void
-i965_render_startup(VADriverContextP ctx)
+i965_render_startup(VADriverContextP ctx, unsigned int vb_offset)
{
struct i965_driver_data *i965 = i965_driver_data(ctx);
struct i965_render_state *render_state = &i965->render_state;
@@ -1203,7 +1191,7 @@ i965_render_startup(VADriverContextP ctx)
(0 << VB0_BUFFER_INDEX_SHIFT) |
VB0_VERTEXDATA |
((4 * 4) << VB0_BUFFER_PITCH_SHIFT));
- OUT_RELOC(ctx, render_state->vb.vertex_buffer, I915_GEM_DOMAIN_VERTEX, 0, 0);
+ OUT_RELOC(ctx, render_state->vb.vertex_buffer, I915_GEM_DOMAIN_VERTEX, 0, vb_offset);
if (IS_IGDNG(i965->intel.device_id))
OUT_RELOC(ctx, render_state->vb.vertex_buffer, I915_GEM_DOMAIN_VERTEX, 0, 12 * 4);
@@ -1268,8 +1256,10 @@ i965_clear_dest_region(VADriverContextP ctx)
}
static void
-i965_surface_render_pipeline_setup(VADriverContextP ctx)
+i965_surface_render_pipeline_setup(VADriverContextP ctx, unsigned int n_rects)
{
+ unsigned int i;
+
intel_batchbuffer_start_atomic(ctx, 0x1000);
intel_batchbuffer_emit_mi_flush(ctx);
i965_clear_dest_region(ctx);
@@ -1283,13 +1273,16 @@ i965_surface_render_pipeline_setup(VADriverContextP ctx)
i965_render_cs_urb_layout(ctx);
i965_render_drawing_rectangle(ctx);
i965_render_vertex_elements(ctx);
- i965_render_startup(ctx);
+ for (i = 0; i < n_rects; i++)
+ i965_render_startup(ctx, 48 * i);
intel_batchbuffer_end_atomic(ctx);
}
static void
-i965_subpic_render_pipeline_setup(VADriverContextP ctx)
+i965_subpic_render_pipeline_setup(VADriverContextP ctx, unsigned int n_rects)
{
+ unsigned int i;
+
intel_batchbuffer_start_atomic(ctx, 0x1000);
intel_batchbuffer_emit_mi_flush(ctx);
i965_render_pipeline_select(ctx);
@@ -1302,7 +1295,8 @@ i965_subpic_render_pipeline_setup(VADriverContextP ctx)
i965_render_cs_urb_layout(ctx);
i965_render_drawing_rectangle(ctx);
i965_render_vertex_elements(ctx);
- i965_render_startup(ctx);
+ for (i = 0; i < n_rects; i++)
+ i965_render_startup(ctx, 48 * i);
intel_batchbuffer_end_atomic(ctx);
}
@@ -1396,45 +1390,39 @@ i965_render_initialize(VADriverContextP ctx)
void
i965_render_put_surface(VADriverContextP ctx,
VASurfaceID surface,
- short srcx,
- short srcy,
- unsigned short srcw,
- unsigned short srch,
- short destx,
- short desty,
- unsigned short destw,
- unsigned short desth)
+ const VARectangle *src_rect,
+ const VARectangle *dst_rect,
+ const VARectangle *cliprects,
+ unsigned int num_cliprects)
{
+ unsigned int n_rects;
+
i965_render_initialize(ctx);
- i965_surface_render_state_setup(ctx, surface,
- srcx, srcy, srcw, srch,
- destx, desty, destw, desth);
- i965_surface_render_pipeline_setup(ctx);
+ n_rects = i965_surface_render_state_setup(ctx, surface,
+ src_rect, dst_rect,
+ cliprects, num_cliprects);
+ i965_surface_render_pipeline_setup(ctx, n_rects);
intel_batchbuffer_flush(ctx);
}
void
i965_render_put_subpic(VADriverContextP ctx,
- VASurfaceID surface,
- short srcx,
- short srcy,
- unsigned short srcw,
- unsigned short srch,
- short destx,
- short desty,
- unsigned short destw,
- unsigned short desth)
+ VASurfaceID surface,
+ const VARectangle *src_rect,
+ const VARectangle *dst_rect,
+ const VARectangle *cliprects,
+ unsigned int num_cliprects)
{
struct i965_driver_data *i965 = i965_driver_data(ctx);
struct object_surface *obj_surface = SURFACE(surface);
struct object_subpic *obj_subpic = SUBPIC(obj_surface->subpic);
+ unsigned int n_rects;
assert(obj_subpic);
i965_render_initialize(ctx);
- i965_subpic_render_state_setup(ctx, surface,
- srcx, srcy, srcw, srch,
- destx, desty, destw, desth);
- i965_subpic_render_pipeline_setup(ctx);
+ n_rects = i965_subpic_render_state_setup(ctx, surface, src_rect, dst_rect,
+ cliprects, num_cliprects);
+ i965_subpic_render_pipeline_setup(ctx, n_rects);
i965_render_upload_image_palette(ctx, obj_subpic->image, 0xff);
intel_batchbuffer_flush(ctx);
}
diff --git a/i965_drv_video/i965_render.h b/i965_drv_video/i965_render.h
index e3dce02..d2e23f1 100644
--- a/i965_drv_video/i965_render.h
+++ b/i965_drv_video/i965_render.h
@@ -28,6 +28,7 @@
#ifndef _I965_RENDER_H_
#define _I965_RENDER_H_
+#define MAX_CLIP_RECTS 80 /* vb_bo:4096 / vb:(3*4*4) */
#define MAX_RENDER_SURFACES 16
#define MAX_SAMPLERS 16
@@ -65,27 +66,20 @@ struct i965_render_state
Bool i965_render_init(VADriverContextP ctx);
Bool i965_render_terminate(VADriverContextP ctx);
+
void i965_render_put_surface(VADriverContextP ctx,
VASurfaceID surface,
- short srcx,
- short srcy,
- unsigned short srcw,
- unsigned short srch,
- short destx,
- short desty,
- unsigned short destw,
- unsigned short desth);
-
+ const VARectangle *src_rect,
+ const VARectangle *dst_rect,
+ const VARectangle *cliprects,
+ unsigned int num_cliprects);
void
i965_render_put_subpic(VADriverContextP ctx,
- VASurfaceID surface,
- short srcx,
- short srcy,
- unsigned short srcw,
- unsigned short srch,
- short destx,
- short desty,
- unsigned short destw,
- unsigned short desth);
+ VASurfaceID surface,
+ const VARectangle *src_rect,
+ const VARectangle *dst_rect,
+ const VARectangle *cliprects,
+ unsigned int num_cliprects);
+
#endif /* _I965_RENDER_H_ */
--
1.5.4.3