diff options
author | Jakob Bornecrantz <jakob@vmware.com> | 2011-10-04 14:13:18 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-10-05 05:17:11 -0400 |
commit | 5deb65cf83ae5aaf4cdfdd85f0ab3117594d9b00 (patch) | |
tree | 57b31c292057c2e54f98798fb3ee5451c8849289 /drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |
parent | 922ade0d16d24be2040be7d55dbb734af779a1dd (diff) |
vmwgfx: Break out dirty submission code
In preperation for screen objects, still leaves the delayed workqueue
for surface updates in place.
Signed-off-by: Jakob Bornecrantz <jakob@vmware.com>
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_kms.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 144 |
1 files changed, 90 insertions, 54 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 7ee8b8e12185..1dbb67e67f21 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -433,6 +433,49 @@ out_unlock: | |||
433 | mutex_unlock(&vfbs->work_lock); | 433 | mutex_unlock(&vfbs->work_lock); |
434 | } | 434 | } |
435 | 435 | ||
436 | static int do_surface_dirty_ldu(struct vmw_private *dev_priv, | ||
437 | struct vmw_framebuffer *framebuffer, | ||
438 | struct vmw_surface *surf, | ||
439 | unsigned flags, unsigned color, | ||
440 | struct drm_clip_rect *clips, | ||
441 | unsigned num_clips, int inc) | ||
442 | { | ||
443 | SVGA3dCopyRect *cr; | ||
444 | int i; | ||
445 | |||
446 | struct { | ||
447 | SVGA3dCmdHeader header; | ||
448 | SVGA3dCmdPresent body; | ||
449 | SVGA3dCopyRect cr; | ||
450 | } *cmd; | ||
451 | |||
452 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd) + (num_clips - 1) * | ||
453 | sizeof(cmd->cr)); | ||
454 | if (unlikely(cmd == NULL)) { | ||
455 | DRM_ERROR("Fifo reserve failed.\n"); | ||
456 | return -ENOMEM; | ||
457 | } | ||
458 | |||
459 | memset(cmd, 0, sizeof(*cmd)); | ||
460 | |||
461 | cmd->header.id = cpu_to_le32(SVGA_3D_CMD_PRESENT); | ||
462 | cmd->header.size = cpu_to_le32(sizeof(cmd->body) + num_clips * | ||
463 | sizeof(cmd->cr)); | ||
464 | cmd->body.sid = cpu_to_le32(surf->res.id); | ||
465 | |||
466 | for (i = 0, cr = &cmd->cr; i < num_clips; i++, cr++, clips += inc) { | ||
467 | cr->x = cpu_to_le16(clips->x1); | ||
468 | cr->y = cpu_to_le16(clips->y1); | ||
469 | cr->srcx = cr->x; | ||
470 | cr->srcy = cr->y; | ||
471 | cr->w = cpu_to_le16(clips->x2 - clips->x1); | ||
472 | cr->h = cpu_to_le16(clips->y2 - clips->y1); | ||
473 | } | ||
474 | |||
475 | vmw_fifo_commit(dev_priv, sizeof(*cmd) + (num_clips - 1) * | ||
476 | sizeof(cmd->cr)); | ||
477 | return 0; | ||
478 | } | ||
436 | 479 | ||
437 | int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer, | 480 | int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer, |
438 | struct drm_file *file_priv, | 481 | struct drm_file *file_priv, |
@@ -446,15 +489,7 @@ int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer, | |||
446 | vmw_framebuffer_to_vfbs(framebuffer); | 489 | vmw_framebuffer_to_vfbs(framebuffer); |
447 | struct vmw_surface *surf = vfbs->surface; | 490 | struct vmw_surface *surf = vfbs->surface; |
448 | struct drm_clip_rect norect; | 491 | struct drm_clip_rect norect; |
449 | SVGA3dCopyRect *cr; | 492 | int ret, inc = 1; |
450 | int i, inc = 1; | ||
451 | int ret; | ||
452 | |||
453 | struct { | ||
454 | SVGA3dCmdHeader header; | ||
455 | SVGA3dCmdPresent body; | ||
456 | SVGA3dCopyRect cr; | ||
457 | } *cmd; | ||
458 | 493 | ||
459 | if (unlikely(vfbs->master != file_priv->master)) | 494 | if (unlikely(vfbs->master != file_priv->master)) |
460 | return -EINVAL; | 495 | return -EINVAL; |
@@ -493,29 +528,10 @@ int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer, | |||
493 | inc = 2; /* skip source rects */ | 528 | inc = 2; /* skip source rects */ |
494 | } | 529 | } |
495 | 530 | ||
496 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd) + (num_clips - 1) * sizeof(cmd->cr)); | 531 | ret = do_surface_dirty_ldu(dev_priv, &vfbs->base, surf, |
497 | if (unlikely(cmd == NULL)) { | 532 | flags, color, |
498 | DRM_ERROR("Fifo reserve failed.\n"); | 533 | clips, num_clips, inc); |
499 | ttm_read_unlock(&vmaster->lock); | ||
500 | return -ENOMEM; | ||
501 | } | ||
502 | |||
503 | memset(cmd, 0, sizeof(*cmd)); | ||
504 | 534 | ||
505 | cmd->header.id = cpu_to_le32(SVGA_3D_CMD_PRESENT); | ||
506 | cmd->header.size = cpu_to_le32(sizeof(cmd->body) + num_clips * sizeof(cmd->cr)); | ||
507 | cmd->body.sid = cpu_to_le32(surf->res.id); | ||
508 | |||
509 | for (i = 0, cr = &cmd->cr; i < num_clips; i++, cr++, clips += inc) { | ||
510 | cr->x = cpu_to_le16(clips->x1); | ||
511 | cr->y = cpu_to_le16(clips->y1); | ||
512 | cr->srcx = cr->x; | ||
513 | cr->srcy = cr->y; | ||
514 | cr->w = cpu_to_le16(clips->x2 - clips->x1); | ||
515 | cr->h = cpu_to_le16(clips->y2 - clips->y1); | ||
516 | } | ||
517 | |||
518 | vmw_fifo_commit(dev_priv, sizeof(*cmd) + (num_clips - 1) * sizeof(cmd->cr)); | ||
519 | ttm_read_unlock(&vmaster->lock); | 535 | ttm_read_unlock(&vmaster->lock); |
520 | return 0; | 536 | return 0; |
521 | } | 537 | } |
@@ -648,6 +664,41 @@ void vmw_framebuffer_dmabuf_destroy(struct drm_framebuffer *framebuffer) | |||
648 | kfree(vfbd); | 664 | kfree(vfbd); |
649 | } | 665 | } |
650 | 666 | ||
667 | static int do_dmabuf_dirty_ldu(struct vmw_private *dev_priv, | ||
668 | struct vmw_framebuffer *framebuffer, | ||
669 | struct vmw_dma_buffer *buffer, | ||
670 | unsigned flags, unsigned color, | ||
671 | struct drm_clip_rect *clips, | ||
672 | unsigned num_clips, int increment) | ||
673 | { | ||
674 | size_t fifo_size; | ||
675 | int i; | ||
676 | |||
677 | struct { | ||
678 | uint32_t header; | ||
679 | SVGAFifoCmdUpdate body; | ||
680 | } *cmd; | ||
681 | |||
682 | fifo_size = sizeof(*cmd) * num_clips; | ||
683 | cmd = vmw_fifo_reserve(dev_priv, fifo_size); | ||
684 | if (unlikely(cmd == NULL)) { | ||
685 | DRM_ERROR("Fifo reserve failed.\n"); | ||
686 | return -ENOMEM; | ||
687 | } | ||
688 | |||
689 | memset(cmd, 0, fifo_size); | ||
690 | for (i = 0; i < num_clips; i++, clips += increment) { | ||
691 | cmd[i].header = cpu_to_le32(SVGA_CMD_UPDATE); | ||
692 | cmd[i].body.x = cpu_to_le32(clips->x1); | ||
693 | cmd[i].body.y = cpu_to_le32(clips->y1); | ||
694 | cmd[i].body.width = cpu_to_le32(clips->x2 - clips->x1); | ||
695 | cmd[i].body.height = cpu_to_le32(clips->y2 - clips->y1); | ||
696 | } | ||
697 | |||
698 | vmw_fifo_commit(dev_priv, fifo_size); | ||
699 | return 0; | ||
700 | } | ||
701 | |||
651 | int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer, | 702 | int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer, |
652 | struct drm_file *file_priv, | 703 | struct drm_file *file_priv, |
653 | unsigned flags, unsigned color, | 704 | unsigned flags, unsigned color, |
@@ -656,13 +707,11 @@ int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer, | |||
656 | { | 707 | { |
657 | struct vmw_private *dev_priv = vmw_priv(framebuffer->dev); | 708 | struct vmw_private *dev_priv = vmw_priv(framebuffer->dev); |
658 | struct vmw_master *vmaster = vmw_master(file_priv->master); | 709 | struct vmw_master *vmaster = vmw_master(file_priv->master); |
710 | struct vmw_framebuffer_dmabuf *vfbd = | ||
711 | vmw_framebuffer_to_vfbd(framebuffer); | ||
712 | struct vmw_dma_buffer *dmabuf = vfbd->buffer; | ||
659 | struct drm_clip_rect norect; | 713 | struct drm_clip_rect norect; |
660 | int ret; | 714 | int ret, increment = 1; |
661 | struct { | ||
662 | uint32_t header; | ||
663 | SVGAFifoCmdUpdate body; | ||
664 | } *cmd; | ||
665 | int i, increment = 1; | ||
666 | 715 | ||
667 | ret = ttm_read_lock(&vmaster->lock, true); | 716 | ret = ttm_read_lock(&vmaster->lock, true); |
668 | if (unlikely(ret != 0)) | 717 | if (unlikely(ret != 0)) |
@@ -679,25 +728,12 @@ int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer, | |||
679 | increment = 2; | 728 | increment = 2; |
680 | } | 729 | } |
681 | 730 | ||
682 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd) * num_clips); | 731 | ret = do_dmabuf_dirty_ldu(dev_priv, &vfbd->base, dmabuf, |
683 | if (unlikely(cmd == NULL)) { | 732 | flags, color, |
684 | DRM_ERROR("Fifo reserve failed.\n"); | 733 | clips, num_clips, increment); |
685 | ttm_read_unlock(&vmaster->lock); | ||
686 | return -ENOMEM; | ||
687 | } | ||
688 | |||
689 | for (i = 0; i < num_clips; i++, clips += increment) { | ||
690 | cmd[i].header = cpu_to_le32(SVGA_CMD_UPDATE); | ||
691 | cmd[i].body.x = cpu_to_le32(clips->x1); | ||
692 | cmd[i].body.y = cpu_to_le32(clips->y1); | ||
693 | cmd[i].body.width = cpu_to_le32(clips->x2 - clips->x1); | ||
694 | cmd[i].body.height = cpu_to_le32(clips->y2 - clips->y1); | ||
695 | } | ||
696 | 734 | ||
697 | vmw_fifo_commit(dev_priv, sizeof(*cmd) * num_clips); | ||
698 | ttm_read_unlock(&vmaster->lock); | 735 | ttm_read_unlock(&vmaster->lock); |
699 | 736 | return ret; | |
700 | return 0; | ||
701 | } | 737 | } |
702 | 738 | ||
703 | static struct drm_framebuffer_funcs vmw_framebuffer_dmabuf_funcs = { | 739 | static struct drm_framebuffer_funcs vmw_framebuffer_dmabuf_funcs = { |