From 90de12a47e26ccc0b4cc8189c76991609481870d Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne 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