diff options
-rw-r--r-- | harddoomdev.c | 21 | ||||
-rw-r--r-- | harddoomdev.h | 2 | ||||
-rw-r--r-- | surface.c | 38 |
3 files changed, 60 insertions, 1 deletions
diff --git a/harddoomdev.c b/harddoomdev.c index 9b327c0..38c32dd 100644 --- a/harddoomdev.c +++ b/harddoomdev.c @@ -43,6 +43,11 @@ void ping_sync(void __iomem *iomem) send_command(iomem, HARDDOOM_CMD_PING_SYNC); } +void set_surf_src_pt(void __iomem *iomem, dma_addr_t page_table) +{ + send_command(iomem, HARDDOOM_CMD_SURF_SRC_PT(page_table)); +} + void set_surf_dst_pt(void __iomem *iomem, dma_addr_t page_table) { send_command(iomem, HARDDOOM_CMD_SURF_DST_PT(page_table)); @@ -97,6 +102,22 @@ void draw_line(struct surface_data *surface_data, struct doomdev_line line) send_command(iomem, HARDDOOM_CMD_DRAW_LINE); } +void copy_rect(struct surface_data *dst_data, struct surface_data *src_data, + struct doomdev_copy_rect rect) +{ + void __iomem *iomem; + + iomem = dst_data->doom_data->iomem; + + set_surf_dst_pt(iomem, dst_data->page_table_dev); + set_surf_src_pt(iomem, src_data->page_table_dev); + set_surf_dims(iomem, dst_data->width, dst_data->height); + set_xy_a(iomem, rect.pos_dst_x, rect.pos_dst_y); + set_xy_b(iomem, rect.pos_src_x, rect.pos_src_y); + + send_command(iomem, HARDDOOM_CMD_COPY_RECT(rect.width, rect.height)); +} + uint32_t doomdev_read_stat(void __iomem *iomem, size_t stat) { return doomdev_read(iomem, HARDDOOM_STATS(stat)); diff --git a/harddoomdev.h b/harddoomdev.h index 05a0b72..2c956f2 100644 --- a/harddoomdev.h +++ b/harddoomdev.h @@ -15,5 +15,7 @@ void ping_sync(void __iomem *iomem); void draw_line(struct surface_data *surface_data, struct doomdev_line line); void fill_rect(struct surface_data *surface_data, struct doomdev_fill_rect rect); +void copy_rect(struct surface_data *dst_data, struct surface_data *src_data, + struct doomdev_copy_rect rect); #endif @@ -17,7 +17,7 @@ long draw_lines(struct file *filp, unsigned long arg) struct doomdev_surf_ioctl_draw_lines *param; struct doomdev_line *lines; int i; - + surface_data = filp->private_data; param = (struct doomdev_surf_ioctl_draw_lines *) arg; lines = (struct doomdev_line *) param->lines_ptr; @@ -55,6 +55,40 @@ long fill_rects(struct file *filp, unsigned long arg) return param->rects_num; } +long copy_rects(struct file *filp, unsigned long arg) +{ + struct surface_data *dst_data; + struct surface_data *src_data; + struct doomdev_surf_ioctl_copy_rects *param; + struct doomdev_copy_rect *rects; + struct fd src_fds; + int i; + + p("in copy rects\n"); + + dst_data = filp->private_data; + param = (struct doomdev_surf_ioctl_copy_rects *) arg; + rects = (struct doomdev_copy_rect *) param->rects_ptr; + + src_fds = fdget(param->surf_src_fd); + src_data = src_fds.file->private_data; + + if (dst_data->doom_data != src_data->doom_data) { + p("copying between devices"); + return -EINVAL; + } + + mutex_lock(&dst_data->doom_data->cmd_mutex); + + for (i = 0; i < param->rects_num; i++) { + copy_rect(dst_data, src_data, rects[i]); + } + + mutex_unlock(&dst_data->doom_data->cmd_mutex); + + return param->rects_num; +} + long surface_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { switch (cmd) { @@ -62,6 +96,8 @@ long surface_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return draw_lines(filp, arg); case DOOMDEV_SURF_IOCTL_FILL_RECTS: return fill_rects(filp, arg); + case DOOMDEV_SURF_IOCTL_COPY_RECTS: + return copy_rects(filp, arg); default: return -1; } |