diff options
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | 107 |
1 files changed, 94 insertions, 13 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index 3eb148667d63..6ccd993e26bf 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | |||
@@ -35,6 +35,23 @@ bool vmw_fifo_have_3d(struct vmw_private *dev_priv) | |||
35 | uint32_t fifo_min, hwversion; | 35 | uint32_t fifo_min, hwversion; |
36 | const struct vmw_fifo_state *fifo = &dev_priv->fifo; | 36 | const struct vmw_fifo_state *fifo = &dev_priv->fifo; |
37 | 37 | ||
38 | if (!(dev_priv->capabilities & SVGA_CAP_3D)) | ||
39 | return false; | ||
40 | |||
41 | if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) { | ||
42 | uint32_t result; | ||
43 | |||
44 | if (!dev_priv->has_mob) | ||
45 | return false; | ||
46 | |||
47 | mutex_lock(&dev_priv->hw_mutex); | ||
48 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_3D); | ||
49 | result = vmw_read(dev_priv, SVGA_REG_DEV_CAP); | ||
50 | mutex_unlock(&dev_priv->hw_mutex); | ||
51 | |||
52 | return (result != 0); | ||
53 | } | ||
54 | |||
38 | if (!(dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO)) | 55 | if (!(dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO)) |
39 | return false; | 56 | return false; |
40 | 57 | ||
@@ -511,24 +528,16 @@ out_err: | |||
511 | } | 528 | } |
512 | 529 | ||
513 | /** | 530 | /** |
514 | * vmw_fifo_emit_dummy_query - emits a dummy query to the fifo. | 531 | * vmw_fifo_emit_dummy_legacy_query - emits a dummy query to the fifo using |
532 | * legacy query commands. | ||
515 | * | 533 | * |
516 | * @dev_priv: The device private structure. | 534 | * @dev_priv: The device private structure. |
517 | * @cid: The hardware context id used for the query. | 535 | * @cid: The hardware context id used for the query. |
518 | * | 536 | * |
519 | * This function is used to emit a dummy occlusion query with | 537 | * See the vmw_fifo_emit_dummy_query documentation. |
520 | * no primitives rendered between query begin and query end. | ||
521 | * It's used to provide a query barrier, in order to know that when | ||
522 | * this query is finished, all preceding queries are also finished. | ||
523 | * | ||
524 | * A Query results structure should have been initialized at the start | ||
525 | * of the dev_priv->dummy_query_bo buffer object. And that buffer object | ||
526 | * must also be either reserved or pinned when this function is called. | ||
527 | * | ||
528 | * Returns -ENOMEM on failure to reserve fifo space. | ||
529 | */ | 538 | */ |
530 | int vmw_fifo_emit_dummy_query(struct vmw_private *dev_priv, | 539 | static int vmw_fifo_emit_dummy_legacy_query(struct vmw_private *dev_priv, |
531 | uint32_t cid) | 540 | uint32_t cid) |
532 | { | 541 | { |
533 | /* | 542 | /* |
534 | * A query wait without a preceding query end will | 543 | * A query wait without a preceding query end will |
@@ -566,3 +575,75 @@ int vmw_fifo_emit_dummy_query(struct vmw_private *dev_priv, | |||
566 | 575 | ||
567 | return 0; | 576 | return 0; |
568 | } | 577 | } |
578 | |||
579 | /** | ||
580 | * vmw_fifo_emit_dummy_gb_query - emits a dummy query to the fifo using | ||
581 | * guest-backed resource query commands. | ||
582 | * | ||
583 | * @dev_priv: The device private structure. | ||
584 | * @cid: The hardware context id used for the query. | ||
585 | * | ||
586 | * See the vmw_fifo_emit_dummy_query documentation. | ||
587 | */ | ||
588 | static int vmw_fifo_emit_dummy_gb_query(struct vmw_private *dev_priv, | ||
589 | uint32_t cid) | ||
590 | { | ||
591 | /* | ||
592 | * A query wait without a preceding query end will | ||
593 | * actually finish all queries for this cid | ||
594 | * without writing to the query result structure. | ||
595 | */ | ||
596 | |||
597 | struct ttm_buffer_object *bo = dev_priv->dummy_query_bo; | ||
598 | struct { | ||
599 | SVGA3dCmdHeader header; | ||
600 | SVGA3dCmdWaitForGBQuery body; | ||
601 | } *cmd; | ||
602 | |||
603 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); | ||
604 | |||
605 | if (unlikely(cmd == NULL)) { | ||
606 | DRM_ERROR("Out of fifo space for dummy query.\n"); | ||
607 | return -ENOMEM; | ||
608 | } | ||
609 | |||
610 | cmd->header.id = SVGA_3D_CMD_WAIT_FOR_GB_QUERY; | ||
611 | cmd->header.size = sizeof(cmd->body); | ||
612 | cmd->body.cid = cid; | ||
613 | cmd->body.type = SVGA3D_QUERYTYPE_OCCLUSION; | ||
614 | BUG_ON(bo->mem.mem_type != VMW_PL_MOB); | ||
615 | cmd->body.mobid = bo->mem.start; | ||
616 | cmd->body.offset = 0; | ||
617 | |||
618 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | ||
619 | |||
620 | return 0; | ||
621 | } | ||
622 | |||
623 | |||
624 | /** | ||
625 | * vmw_fifo_emit_dummy_gb_query - emits a dummy query to the fifo using | ||
626 | * appropriate resource query commands. | ||
627 | * | ||
628 | * @dev_priv: The device private structure. | ||
629 | * @cid: The hardware context id used for the query. | ||
630 | * | ||
631 | * This function is used to emit a dummy occlusion query with | ||
632 | * no primitives rendered between query begin and query end. | ||
633 | * It's used to provide a query barrier, in order to know that when | ||
634 | * this query is finished, all preceding queries are also finished. | ||
635 | * | ||
636 | * A Query results structure should have been initialized at the start | ||
637 | * of the dev_priv->dummy_query_bo buffer object. And that buffer object | ||
638 | * must also be either reserved or pinned when this function is called. | ||
639 | * | ||
640 | * Returns -ENOMEM on failure to reserve fifo space. | ||
641 | */ | ||
642 | int vmw_fifo_emit_dummy_query(struct vmw_private *dev_priv, | ||
643 | uint32_t cid) | ||
644 | { | ||
645 | if (dev_priv->has_mob) | ||
646 | return vmw_fifo_emit_dummy_gb_query(dev_priv, cid); | ||
647 | |||
648 | return vmw_fifo_emit_dummy_legacy_query(dev_priv, cid); | ||
649 | } | ||