diff options
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c')
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 227 |
1 files changed, 128 insertions, 99 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 87df0b3674fd..7bfdaa163a33 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |||
| @@ -422,28 +422,91 @@ static int vmw_resources_validate(struct vmw_sw_context *sw_context) | |||
| 422 | return 0; | 422 | return 0; |
| 423 | } | 423 | } |
| 424 | 424 | ||
| 425 | |||
| 426 | /** | ||
| 427 | * vmw_cmd_res_reloc_add - Add a resource to a software context's | ||
| 428 | * relocation- and validation lists. | ||
| 429 | * | ||
| 430 | * @dev_priv: Pointer to a struct vmw_private identifying the device. | ||
| 431 | * @sw_context: Pointer to the software context. | ||
| 432 | * @res_type: Resource type. | ||
| 433 | * @id_loc: Pointer to where the id that needs translation is located. | ||
| 434 | * @res: Valid pointer to a struct vmw_resource. | ||
| 435 | * @p_val: If non null, a pointer to the struct vmw_resource_validate_node | ||
| 436 | * used for this resource is returned here. | ||
| 437 | */ | ||
| 438 | static int vmw_cmd_res_reloc_add(struct vmw_private *dev_priv, | ||
| 439 | struct vmw_sw_context *sw_context, | ||
| 440 | enum vmw_res_type res_type, | ||
| 441 | uint32_t *id_loc, | ||
| 442 | struct vmw_resource *res, | ||
| 443 | struct vmw_resource_val_node **p_val) | ||
| 444 | { | ||
| 445 | int ret; | ||
| 446 | struct vmw_resource_val_node *node; | ||
| 447 | |||
| 448 | *p_val = NULL; | ||
| 449 | ret = vmw_resource_relocation_add(&sw_context->res_relocations, | ||
| 450 | res, | ||
| 451 | id_loc - sw_context->buf_start); | ||
| 452 | if (unlikely(ret != 0)) | ||
| 453 | goto out_err; | ||
| 454 | |||
| 455 | ret = vmw_resource_val_add(sw_context, res, &node); | ||
| 456 | if (unlikely(ret != 0)) | ||
| 457 | goto out_err; | ||
| 458 | |||
| 459 | if (res_type == vmw_res_context && dev_priv->has_mob && | ||
| 460 | node->first_usage) { | ||
| 461 | |||
| 462 | /* | ||
| 463 | * Put contexts first on the list to be able to exit | ||
| 464 | * list traversal for contexts early. | ||
| 465 | */ | ||
| 466 | list_del(&node->head); | ||
| 467 | list_add(&node->head, &sw_context->resource_list); | ||
| 468 | |||
| 469 | ret = vmw_resource_context_res_add(dev_priv, sw_context, res); | ||
| 470 | if (unlikely(ret != 0)) | ||
| 471 | goto out_err; | ||
| 472 | node->staged_bindings = | ||
| 473 | kzalloc(sizeof(*node->staged_bindings), GFP_KERNEL); | ||
| 474 | if (node->staged_bindings == NULL) { | ||
| 475 | DRM_ERROR("Failed to allocate context binding " | ||
| 476 | "information.\n"); | ||
| 477 | goto out_err; | ||
| 478 | } | ||
| 479 | INIT_LIST_HEAD(&node->staged_bindings->list); | ||
| 480 | } | ||
| 481 | |||
| 482 | if (p_val) | ||
| 483 | *p_val = node; | ||
| 484 | |||
| 485 | out_err: | ||
| 486 | return ret; | ||
| 487 | } | ||
| 488 | |||
| 489 | |||
| 425 | /** | 490 | /** |
| 426 | * vmw_cmd_compat_res_check - Check that a resource is present and if so, put it | 491 | * vmw_cmd_res_check - Check that a resource is present and if so, put it |
| 427 | * on the resource validate list unless it's already there. | 492 | * on the resource validate list unless it's already there. |
| 428 | * | 493 | * |
| 429 | * @dev_priv: Pointer to a device private structure. | 494 | * @dev_priv: Pointer to a device private structure. |
| 430 | * @sw_context: Pointer to the software context. | 495 | * @sw_context: Pointer to the software context. |
| 431 | * @res_type: Resource type. | 496 | * @res_type: Resource type. |
| 432 | * @converter: User-space visisble type specific information. | 497 | * @converter: User-space visisble type specific information. |
| 433 | * @id: user-space resource id handle. | ||
| 434 | * @id_loc: Pointer to the location in the command buffer currently being | 498 | * @id_loc: Pointer to the location in the command buffer currently being |
| 435 | * parsed from where the user-space resource id handle is located. | 499 | * parsed from where the user-space resource id handle is located. |
| 436 | * @p_val: Pointer to pointer to resource validalidation node. Populated | 500 | * @p_val: Pointer to pointer to resource validalidation node. Populated |
| 437 | * on exit. | 501 | * on exit. |
| 438 | */ | 502 | */ |
| 439 | static int | 503 | static int |
| 440 | vmw_cmd_compat_res_check(struct vmw_private *dev_priv, | 504 | vmw_cmd_res_check(struct vmw_private *dev_priv, |
| 441 | struct vmw_sw_context *sw_context, | 505 | struct vmw_sw_context *sw_context, |
| 442 | enum vmw_res_type res_type, | 506 | enum vmw_res_type res_type, |
| 443 | const struct vmw_user_resource_conv *converter, | 507 | const struct vmw_user_resource_conv *converter, |
| 444 | uint32_t id, | 508 | uint32_t *id_loc, |
| 445 | uint32_t *id_loc, | 509 | struct vmw_resource_val_node **p_val) |
| 446 | struct vmw_resource_val_node **p_val) | ||
| 447 | { | 510 | { |
| 448 | struct vmw_res_cache_entry *rcache = | 511 | struct vmw_res_cache_entry *rcache = |
| 449 | &sw_context->res_cache[res_type]; | 512 | &sw_context->res_cache[res_type]; |
| @@ -451,7 +514,7 @@ vmw_cmd_compat_res_check(struct vmw_private *dev_priv, | |||
| 451 | struct vmw_resource_val_node *node; | 514 | struct vmw_resource_val_node *node; |
| 452 | int ret; | 515 | int ret; |
| 453 | 516 | ||
| 454 | if (id == SVGA3D_INVALID_ID) { | 517 | if (*id_loc == SVGA3D_INVALID_ID) { |
| 455 | if (p_val) | 518 | if (p_val) |
| 456 | *p_val = NULL; | 519 | *p_val = NULL; |
| 457 | if (res_type == vmw_res_context) { | 520 | if (res_type == vmw_res_context) { |
| @@ -466,7 +529,7 @@ vmw_cmd_compat_res_check(struct vmw_private *dev_priv, | |||
| 466 | * resource | 529 | * resource |
| 467 | */ | 530 | */ |
| 468 | 531 | ||
| 469 | if (likely(rcache->valid && id == rcache->handle)) { | 532 | if (likely(rcache->valid && *id_loc == rcache->handle)) { |
| 470 | const struct vmw_resource *res = rcache->res; | 533 | const struct vmw_resource *res = rcache->res; |
| 471 | 534 | ||
| 472 | rcache->node->first_usage = false; | 535 | rcache->node->first_usage = false; |
| @@ -480,49 +543,28 @@ vmw_cmd_compat_res_check(struct vmw_private *dev_priv, | |||
| 480 | 543 | ||
| 481 | ret = vmw_user_resource_lookup_handle(dev_priv, | 544 | ret = vmw_user_resource_lookup_handle(dev_priv, |
| 482 | sw_context->fp->tfile, | 545 | sw_context->fp->tfile, |
| 483 | id, | 546 | *id_loc, |
| 484 | converter, | 547 | converter, |
| 485 | &res); | 548 | &res); |
| 486 | if (unlikely(ret != 0)) { | 549 | if (unlikely(ret != 0)) { |
| 487 | DRM_ERROR("Could not find or use resource 0x%08x.\n", | 550 | DRM_ERROR("Could not find or use resource 0x%08x.\n", |
| 488 | (unsigned) id); | 551 | (unsigned) *id_loc); |
| 489 | dump_stack(); | 552 | dump_stack(); |
| 490 | return ret; | 553 | return ret; |
| 491 | } | 554 | } |
| 492 | 555 | ||
| 493 | rcache->valid = true; | 556 | rcache->valid = true; |
| 494 | rcache->res = res; | 557 | rcache->res = res; |
| 495 | rcache->handle = id; | 558 | rcache->handle = *id_loc; |
| 496 | |||
| 497 | ret = vmw_resource_relocation_add(&sw_context->res_relocations, | ||
| 498 | res, | ||
| 499 | id_loc - sw_context->buf_start); | ||
| 500 | if (unlikely(ret != 0)) | ||
| 501 | goto out_no_reloc; | ||
| 502 | 559 | ||
| 503 | ret = vmw_resource_val_add(sw_context, res, &node); | 560 | ret = vmw_cmd_res_reloc_add(dev_priv, sw_context, res_type, id_loc, |
| 561 | res, &node); | ||
| 504 | if (unlikely(ret != 0)) | 562 | if (unlikely(ret != 0)) |
| 505 | goto out_no_reloc; | 563 | goto out_no_reloc; |
| 506 | 564 | ||
| 507 | rcache->node = node; | 565 | rcache->node = node; |
| 508 | if (p_val) | 566 | if (p_val) |
| 509 | *p_val = node; | 567 | *p_val = node; |
| 510 | |||
| 511 | if (dev_priv->has_mob && node->first_usage && | ||
| 512 | res_type == vmw_res_context) { | ||
| 513 | ret = vmw_resource_context_res_add(dev_priv, sw_context, res); | ||
| 514 | if (unlikely(ret != 0)) | ||
| 515 | goto out_no_reloc; | ||
| 516 | node->staged_bindings = | ||
| 517 | kzalloc(sizeof(*node->staged_bindings), GFP_KERNEL); | ||
| 518 | if (node->staged_bindings == NULL) { | ||
| 519 | DRM_ERROR("Failed to allocate context binding " | ||
| 520 | "information.\n"); | ||
| 521 | goto out_no_reloc; | ||
| 522 | } | ||
| 523 | INIT_LIST_HEAD(&node->staged_bindings->list); | ||
| 524 | } | ||
| 525 | |||
| 526 | vmw_resource_unreference(&res); | 568 | vmw_resource_unreference(&res); |
| 527 | return 0; | 569 | return 0; |
| 528 | 570 | ||
| @@ -534,31 +576,6 @@ out_no_reloc: | |||
| 534 | } | 576 | } |
| 535 | 577 | ||
| 536 | /** | 578 | /** |
| 537 | * vmw_cmd_res_check - Check that a resource is present and if so, put it | ||
| 538 | * on the resource validate list unless it's already there. | ||
| 539 | * | ||
| 540 | * @dev_priv: Pointer to a device private structure. | ||
| 541 | * @sw_context: Pointer to the software context. | ||
| 542 | * @res_type: Resource type. | ||
| 543 | * @converter: User-space visisble type specific information. | ||
| 544 | * @id_loc: Pointer to the location in the command buffer currently being | ||
| 545 | * parsed from where the user-space resource id handle is located. | ||
| 546 | * @p_val: Pointer to pointer to resource validalidation node. Populated | ||
| 547 | * on exit. | ||
| 548 | */ | ||
| 549 | static int | ||
| 550 | vmw_cmd_res_check(struct vmw_private *dev_priv, | ||
| 551 | struct vmw_sw_context *sw_context, | ||
| 552 | enum vmw_res_type res_type, | ||
| 553 | const struct vmw_user_resource_conv *converter, | ||
| 554 | uint32_t *id_loc, | ||
| 555 | struct vmw_resource_val_node **p_val) | ||
| 556 | { | ||
| 557 | return vmw_cmd_compat_res_check(dev_priv, sw_context, res_type, | ||
| 558 | converter, *id_loc, id_loc, p_val); | ||
| 559 | } | ||
| 560 | |||
| 561 | /** | ||
| 562 | * vmw_rebind_contexts - Rebind all resources previously bound to | 579 | * vmw_rebind_contexts - Rebind all resources previously bound to |
| 563 | * referenced contexts. | 580 | * referenced contexts. |
| 564 | * | 581 | * |
| @@ -572,8 +589,8 @@ static int vmw_rebind_contexts(struct vmw_sw_context *sw_context) | |||
| 572 | int ret; | 589 | int ret; |
| 573 | 590 | ||
| 574 | list_for_each_entry(val, &sw_context->resource_list, head) { | 591 | list_for_each_entry(val, &sw_context->resource_list, head) { |
| 575 | if (likely(!val->staged_bindings)) | 592 | if (unlikely(!val->staged_bindings)) |
| 576 | continue; | 593 | break; |
| 577 | 594 | ||
| 578 | ret = vmw_context_rebind_all(val->res); | 595 | ret = vmw_context_rebind_all(val->res); |
| 579 | if (unlikely(ret != 0)) { | 596 | if (unlikely(ret != 0)) { |
| @@ -1626,13 +1643,14 @@ static int vmw_cmd_shader_define(struct vmw_private *dev_priv, | |||
| 1626 | } *cmd; | 1643 | } *cmd; |
| 1627 | int ret; | 1644 | int ret; |
| 1628 | size_t size; | 1645 | size_t size; |
| 1646 | struct vmw_resource_val_node *val; | ||
| 1629 | 1647 | ||
| 1630 | cmd = container_of(header, struct vmw_shader_define_cmd, | 1648 | cmd = container_of(header, struct vmw_shader_define_cmd, |
| 1631 | header); | 1649 | header); |
| 1632 | 1650 | ||
| 1633 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, | 1651 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, |
| 1634 | user_context_converter, &cmd->body.cid, | 1652 | user_context_converter, &cmd->body.cid, |
| 1635 | NULL); | 1653 | &val); |
| 1636 | if (unlikely(ret != 0)) | 1654 | if (unlikely(ret != 0)) |
| 1637 | return ret; | 1655 | return ret; |
| 1638 | 1656 | ||
| @@ -1640,11 +1658,11 @@ static int vmw_cmd_shader_define(struct vmw_private *dev_priv, | |||
| 1640 | return 0; | 1658 | return 0; |
| 1641 | 1659 | ||
| 1642 | size = cmd->header.size - sizeof(cmd->body); | 1660 | size = cmd->header.size - sizeof(cmd->body); |
| 1643 | ret = vmw_compat_shader_add(sw_context->fp->shman, | 1661 | ret = vmw_compat_shader_add(dev_priv, |
| 1662 | vmw_context_res_man(val->res), | ||
| 1644 | cmd->body.shid, cmd + 1, | 1663 | cmd->body.shid, cmd + 1, |
| 1645 | cmd->body.type, size, | 1664 | cmd->body.type, size, |
| 1646 | sw_context->fp->tfile, | 1665 | &sw_context->staged_cmd_res); |
| 1647 | &sw_context->staged_shaders); | ||
| 1648 | if (unlikely(ret != 0)) | 1666 | if (unlikely(ret != 0)) |
| 1649 | return ret; | 1667 | return ret; |
| 1650 | 1668 | ||
| @@ -1672,23 +1690,24 @@ static int vmw_cmd_shader_destroy(struct vmw_private *dev_priv, | |||
| 1672 | SVGA3dCmdDestroyShader body; | 1690 | SVGA3dCmdDestroyShader body; |
| 1673 | } *cmd; | 1691 | } *cmd; |
| 1674 | int ret; | 1692 | int ret; |
| 1693 | struct vmw_resource_val_node *val; | ||
| 1675 | 1694 | ||
| 1676 | cmd = container_of(header, struct vmw_shader_destroy_cmd, | 1695 | cmd = container_of(header, struct vmw_shader_destroy_cmd, |
| 1677 | header); | 1696 | header); |
| 1678 | 1697 | ||
| 1679 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, | 1698 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, |
| 1680 | user_context_converter, &cmd->body.cid, | 1699 | user_context_converter, &cmd->body.cid, |
| 1681 | NULL); | 1700 | &val); |
| 1682 | if (unlikely(ret != 0)) | 1701 | if (unlikely(ret != 0)) |
| 1683 | return ret; | 1702 | return ret; |
| 1684 | 1703 | ||
| 1685 | if (unlikely(!dev_priv->has_mob)) | 1704 | if (unlikely(!dev_priv->has_mob)) |
| 1686 | return 0; | 1705 | return 0; |
| 1687 | 1706 | ||
| 1688 | ret = vmw_compat_shader_remove(sw_context->fp->shman, | 1707 | ret = vmw_compat_shader_remove(vmw_context_res_man(val->res), |
| 1689 | cmd->body.shid, | 1708 | cmd->body.shid, |
| 1690 | cmd->body.type, | 1709 | cmd->body.type, |
| 1691 | &sw_context->staged_shaders); | 1710 | &sw_context->staged_cmd_res); |
| 1692 | if (unlikely(ret != 0)) | 1711 | if (unlikely(ret != 0)) |
| 1693 | return ret; | 1712 | return ret; |
| 1694 | 1713 | ||
| @@ -1715,7 +1734,9 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, | |||
| 1715 | SVGA3dCmdHeader header; | 1734 | SVGA3dCmdHeader header; |
| 1716 | SVGA3dCmdSetShader body; | 1735 | SVGA3dCmdSetShader body; |
| 1717 | } *cmd; | 1736 | } *cmd; |
| 1718 | struct vmw_resource_val_node *ctx_node; | 1737 | struct vmw_resource_val_node *ctx_node, *res_node = NULL; |
| 1738 | struct vmw_ctx_bindinfo bi; | ||
| 1739 | struct vmw_resource *res = NULL; | ||
| 1719 | int ret; | 1740 | int ret; |
| 1720 | 1741 | ||
| 1721 | cmd = container_of(header, struct vmw_set_shader_cmd, | 1742 | cmd = container_of(header, struct vmw_set_shader_cmd, |
| @@ -1727,32 +1748,40 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, | |||
| 1727 | if (unlikely(ret != 0)) | 1748 | if (unlikely(ret != 0)) |
| 1728 | return ret; | 1749 | return ret; |
| 1729 | 1750 | ||
| 1730 | if (dev_priv->has_mob) { | 1751 | if (!dev_priv->has_mob) |
| 1731 | struct vmw_ctx_bindinfo bi; | 1752 | return 0; |
| 1732 | struct vmw_resource_val_node *res_node; | 1753 | |
| 1733 | u32 shid = cmd->body.shid; | 1754 | if (cmd->body.shid != SVGA3D_INVALID_ID) { |
| 1734 | 1755 | res = vmw_compat_shader_lookup | |
| 1735 | if (shid != SVGA3D_INVALID_ID) | 1756 | (vmw_context_res_man(ctx_node->res), |
| 1736 | (void) vmw_compat_shader_lookup(sw_context->fp->shman, | 1757 | cmd->body.shid, |
| 1737 | cmd->body.type, | 1758 | cmd->body.type); |
| 1738 | &shid); | 1759 | |
| 1739 | 1760 | if (!IS_ERR(res)) { | |
| 1740 | ret = vmw_cmd_compat_res_check(dev_priv, sw_context, | 1761 | ret = vmw_cmd_res_reloc_add(dev_priv, sw_context, |
| 1741 | vmw_res_shader, | 1762 | vmw_res_shader, |
| 1742 | user_shader_converter, | 1763 | &cmd->body.shid, res, |
| 1743 | shid, | 1764 | &res_node); |
| 1744 | &cmd->body.shid, &res_node); | 1765 | vmw_resource_unreference(&res); |
| 1766 | if (unlikely(ret != 0)) | ||
| 1767 | return ret; | ||
| 1768 | } | ||
| 1769 | } | ||
| 1770 | |||
| 1771 | if (!res_node) { | ||
| 1772 | ret = vmw_cmd_res_check(dev_priv, sw_context, | ||
| 1773 | vmw_res_shader, | ||
| 1774 | user_shader_converter, | ||
| 1775 | &cmd->body.shid, &res_node); | ||
| 1745 | if (unlikely(ret != 0)) | 1776 | if (unlikely(ret != 0)) |
| 1746 | return ret; | 1777 | return ret; |
| 1747 | |||
| 1748 | bi.ctx = ctx_node->res; | ||
| 1749 | bi.res = res_node ? res_node->res : NULL; | ||
| 1750 | bi.bt = vmw_ctx_binding_shader; | ||
| 1751 | bi.i1.shader_type = cmd->body.type; | ||
| 1752 | return vmw_context_binding_add(ctx_node->staged_bindings, &bi); | ||
| 1753 | } | 1778 | } |
| 1754 | 1779 | ||
| 1755 | return 0; | 1780 | bi.ctx = ctx_node->res; |
| 1781 | bi.res = res_node ? res_node->res : NULL; | ||
| 1782 | bi.bt = vmw_ctx_binding_shader; | ||
| 1783 | bi.i1.shader_type = cmd->body.type; | ||
| 1784 | return vmw_context_binding_add(ctx_node->staged_bindings, &bi); | ||
| 1756 | } | 1785 | } |
| 1757 | 1786 | ||
| 1758 | /** | 1787 | /** |
| @@ -2394,6 +2423,8 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, | |||
| 2394 | } | 2423 | } |
| 2395 | } | 2424 | } |
| 2396 | 2425 | ||
| 2426 | |||
| 2427 | |||
| 2397 | int vmw_execbuf_process(struct drm_file *file_priv, | 2428 | int vmw_execbuf_process(struct drm_file *file_priv, |
| 2398 | struct vmw_private *dev_priv, | 2429 | struct vmw_private *dev_priv, |
| 2399 | void __user *user_commands, | 2430 | void __user *user_commands, |
| @@ -2453,7 +2484,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, | |||
| 2453 | goto out_unlock; | 2484 | goto out_unlock; |
| 2454 | sw_context->res_ht_initialized = true; | 2485 | sw_context->res_ht_initialized = true; |
| 2455 | } | 2486 | } |
| 2456 | INIT_LIST_HEAD(&sw_context->staged_shaders); | 2487 | INIT_LIST_HEAD(&sw_context->staged_cmd_res); |
| 2457 | 2488 | ||
| 2458 | INIT_LIST_HEAD(&resource_list); | 2489 | INIT_LIST_HEAD(&resource_list); |
| 2459 | ret = vmw_cmd_check_all(dev_priv, sw_context, kernel_commands, | 2490 | ret = vmw_cmd_check_all(dev_priv, sw_context, kernel_commands, |
| @@ -2548,8 +2579,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, | |||
| 2548 | } | 2579 | } |
| 2549 | 2580 | ||
| 2550 | list_splice_init(&sw_context->resource_list, &resource_list); | 2581 | list_splice_init(&sw_context->resource_list, &resource_list); |
| 2551 | vmw_compat_shaders_commit(sw_context->fp->shman, | 2582 | vmw_cmdbuf_res_commit(&sw_context->staged_cmd_res); |
| 2552 | &sw_context->staged_shaders); | ||
| 2553 | mutex_unlock(&dev_priv->cmdbuf_mutex); | 2583 | mutex_unlock(&dev_priv->cmdbuf_mutex); |
| 2554 | 2584 | ||
| 2555 | /* | 2585 | /* |
| @@ -2576,8 +2606,7 @@ out_unlock: | |||
| 2576 | list_splice_init(&sw_context->resource_list, &resource_list); | 2606 | list_splice_init(&sw_context->resource_list, &resource_list); |
| 2577 | error_resource = sw_context->error_resource; | 2607 | error_resource = sw_context->error_resource; |
| 2578 | sw_context->error_resource = NULL; | 2608 | sw_context->error_resource = NULL; |
| 2579 | vmw_compat_shaders_revert(sw_context->fp->shman, | 2609 | vmw_cmdbuf_res_revert(&sw_context->staged_cmd_res); |
| 2580 | &sw_context->staged_shaders); | ||
| 2581 | mutex_unlock(&dev_priv->cmdbuf_mutex); | 2610 | mutex_unlock(&dev_priv->cmdbuf_mutex); |
| 2582 | 2611 | ||
| 2583 | /* | 2612 | /* |
