Rev 4075 | Rev 5078 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4075 | Rev 4569 | ||
---|---|---|---|
Line 36... | Line 36... | ||
36 | * @base: The TTM base object handling user-space visibility. |
36 | * @base: The TTM base object handling user-space visibility. |
37 | * @srf: The surface metadata. |
37 | * @srf: The surface metadata. |
38 | * @size: TTM accounting size for the surface. |
38 | * @size: TTM accounting size for the surface. |
39 | */ |
39 | */ |
40 | struct vmw_user_surface { |
40 | struct vmw_user_surface { |
41 | struct ttm_base_object base; |
41 | struct ttm_prime_object prime; |
42 | struct vmw_surface srf; |
42 | struct vmw_surface srf; |
43 | uint32_t size; |
43 | uint32_t size; |
44 | uint32_t backup_handle; |
- | |
45 | }; |
44 | }; |
Line 46... | Line 45... | ||
46 | 45 | ||
47 | /** |
46 | /** |
48 | * struct vmw_surface_offset - Backing store mip level offset info |
47 | * struct vmw_surface_offset - Backing store mip level offset info |
Line 66... | Line 65... | ||
66 | static int vmw_legacy_srf_unbind(struct vmw_resource *res, |
65 | static int vmw_legacy_srf_unbind(struct vmw_resource *res, |
67 | bool readback, |
66 | bool readback, |
68 | struct ttm_validate_buffer *val_buf); |
67 | struct ttm_validate_buffer *val_buf); |
69 | static int vmw_legacy_srf_create(struct vmw_resource *res); |
68 | static int vmw_legacy_srf_create(struct vmw_resource *res); |
70 | static int vmw_legacy_srf_destroy(struct vmw_resource *res); |
69 | static int vmw_legacy_srf_destroy(struct vmw_resource *res); |
- | 70 | static int vmw_gb_surface_create(struct vmw_resource *res); |
|
- | 71 | static int vmw_gb_surface_bind(struct vmw_resource *res, |
|
- | 72 | struct ttm_validate_buffer *val_buf); |
|
- | 73 | static int vmw_gb_surface_unbind(struct vmw_resource *res, |
|
- | 74 | bool readback, |
|
- | 75 | struct ttm_validate_buffer *val_buf); |
|
- | 76 | static int vmw_gb_surface_destroy(struct vmw_resource *res); |
|
- | 77 | ||
Line 71... | Line 78... | ||
71 | 78 | ||
72 | static const struct vmw_user_resource_conv user_surface_conv = { |
79 | static const struct vmw_user_resource_conv user_surface_conv = { |
73 | .object_type = VMW_RES_SURFACE, |
80 | .object_type = VMW_RES_SURFACE, |
74 | .base_obj_to_res = vmw_user_surface_base_to_res, |
81 | .base_obj_to_res = vmw_user_surface_base_to_res, |
Line 91... | Line 98... | ||
91 | .destroy = &vmw_legacy_srf_destroy, |
98 | .destroy = &vmw_legacy_srf_destroy, |
92 | .bind = &vmw_legacy_srf_bind, |
99 | .bind = &vmw_legacy_srf_bind, |
93 | .unbind = &vmw_legacy_srf_unbind |
100 | .unbind = &vmw_legacy_srf_unbind |
94 | }; |
101 | }; |
Line -... | Line 102... | ||
- | 102 | ||
- | 103 | static const struct vmw_res_func vmw_gb_surface_func = { |
|
- | 104 | .res_type = vmw_res_surface, |
|
- | 105 | .needs_backup = true, |
|
- | 106 | .may_evict = true, |
|
- | 107 | .type_name = "guest backed surfaces", |
|
- | 108 | .backup_placement = &vmw_mob_placement, |
|
- | 109 | .create = vmw_gb_surface_create, |
|
- | 110 | .destroy = vmw_gb_surface_destroy, |
|
- | 111 | .bind = vmw_gb_surface_bind, |
|
- | 112 | .unbind = vmw_gb_surface_unbind |
|
- | 113 | }; |
|
95 | 114 | ||
96 | /** |
115 | /** |
97 | * struct vmw_surface_dma - SVGA3D DMA command |
116 | * struct vmw_surface_dma - SVGA3D DMA command |
98 | */ |
117 | */ |
99 | struct vmw_surface_dma { |
118 | struct vmw_surface_dma { |
Line 289... | Line 308... | ||
289 | 308 | ||
290 | struct vmw_private *dev_priv = res->dev_priv; |
309 | struct vmw_private *dev_priv = res->dev_priv; |
291 | struct vmw_surface *srf; |
310 | struct vmw_surface *srf; |
Line -... | Line 311... | ||
- | 311 | void *cmd; |
|
- | 312 | ||
- | 313 | if (res->func->destroy == vmw_gb_surface_destroy) { |
|
- | 314 | (void) vmw_gb_surface_destroy(res); |
|
- | 315 | return; |
|
292 | void *cmd; |
316 | } |
Line 293... | Line 317... | ||
293 | 317 | ||
294 | if (res->id != -1) { |
318 | if (res->id != -1) { |
295 | 319 | ||
Line 547... | Line 571... | ||
547 | { |
571 | { |
548 | int ret; |
572 | int ret; |
549 | struct vmw_resource *res = &srf->res; |
573 | struct vmw_resource *res = &srf->res; |
Line 550... | Line 574... | ||
550 | 574 | ||
- | 575 | BUG_ON(res_free == NULL); |
|
551 | BUG_ON(res_free == NULL); |
576 | if (!dev_priv->has_mob) |
552 | (void) vmw_3d_resource_inc(dev_priv, false); |
577 | (void) vmw_3d_resource_inc(dev_priv, false); |
- | 578 | ret = vmw_resource_init(dev_priv, res, true, res_free, |
|
553 | ret = vmw_resource_init(dev_priv, res, true, res_free, |
579 | (dev_priv->has_mob) ? &vmw_gb_surface_func : |
Line 554... | Line 580... | ||
554 | &vmw_legacy_surface_func); |
580 | &vmw_legacy_surface_func); |
- | 581 | ||
555 | 582 | if (unlikely(ret != 0)) { |
|
556 | if (unlikely(ret != 0)) { |
583 | if (!dev_priv->has_mob) |
557 | vmw_3d_resource_dec(dev_priv, false); |
584 | vmw_3d_resource_dec(dev_priv, false); |
558 | res_free(res); |
585 | res_free(res); |
Line 578... | Line 605... | ||
578 | * for the user-visible object identified by the TTM base object @base. |
605 | * for the user-visible object identified by the TTM base object @base. |
579 | */ |
606 | */ |
580 | static struct vmw_resource * |
607 | static struct vmw_resource * |
581 | vmw_user_surface_base_to_res(struct ttm_base_object *base) |
608 | vmw_user_surface_base_to_res(struct ttm_base_object *base) |
582 | { |
609 | { |
583 | return &(container_of(base, struct vmw_user_surface, base)->srf.res); |
610 | return &(container_of(base, struct vmw_user_surface, |
- | 611 | prime.base)->srf.res); |
|
584 | } |
612 | } |
Line 585... | Line 613... | ||
585 | 613 | ||
586 | /** |
614 | /** |
587 | * vmw_user_surface_free - User visible surface resource destructor |
615 | * vmw_user_surface_free - User visible surface resource destructor |
Line 614... | Line 642... | ||
614 | */ |
642 | */ |
615 | static void vmw_user_surface_base_release(struct ttm_base_object **p_base) |
643 | static void vmw_user_surface_base_release(struct ttm_base_object **p_base) |
616 | { |
644 | { |
617 | struct ttm_base_object *base = *p_base; |
645 | struct ttm_base_object *base = *p_base; |
618 | struct vmw_user_surface *user_srf = |
646 | struct vmw_user_surface *user_srf = |
619 | container_of(base, struct vmw_user_surface, base); |
647 | container_of(base, struct vmw_user_surface, prime.base); |
620 | struct vmw_resource *res = &user_srf->srf.res; |
648 | struct vmw_resource *res = &user_srf->srf.res; |
Line 621... | Line 649... | ||
621 | 649 | ||
622 | *p_base = NULL; |
650 | *p_base = NULL; |
623 | vmw_resource_unreference(&res); |
651 | vmw_resource_unreference(&res); |
Line 731... | Line 759... | ||
731 | goto out_no_copy; |
759 | goto out_no_copy; |
732 | } |
760 | } |
Line 733... | Line 761... | ||
733 | 761 | ||
734 | srf->base_size = *srf->sizes; |
762 | srf->base_size = *srf->sizes; |
735 | srf->autogen_filter = SVGA3D_TEX_FILTER_NONE; |
763 | srf->autogen_filter = SVGA3D_TEX_FILTER_NONE; |
Line 736... | Line 764... | ||
736 | srf->multisample_count = 1; |
764 | srf->multisample_count = 0; |
737 | 765 | ||
738 | cur_bo_offset = 0; |
766 | cur_bo_offset = 0; |
Line 772... | Line 800... | ||
772 | } else { |
800 | } else { |
773 | srf->snooper.image = NULL; |
801 | srf->snooper.image = NULL; |
774 | } |
802 | } |
775 | srf->snooper.crtc = NULL; |
803 | srf->snooper.crtc = NULL; |
Line 776... | Line 804... | ||
776 | 804 | ||
777 | user_srf->base.shareable = false; |
805 | user_srf->prime.base.shareable = false; |
Line 778... | Line 806... | ||
778 | user_srf->base.tfile = NULL; |
806 | user_srf->prime.base.tfile = NULL; |
779 | 807 | ||
780 | /** |
808 | /** |
781 | * From this point, the generic resource management functions |
809 | * From this point, the generic resource management functions |
Line 785... | Line 813... | ||
785 | ret = vmw_surface_init(dev_priv, srf, vmw_user_surface_free); |
813 | ret = vmw_surface_init(dev_priv, srf, vmw_user_surface_free); |
786 | if (unlikely(ret != 0)) |
814 | if (unlikely(ret != 0)) |
787 | goto out_unlock; |
815 | goto out_unlock; |
Line 788... | Line 816... | ||
788 | 816 | ||
789 | tmp = vmw_resource_reference(&srf->res); |
817 | tmp = vmw_resource_reference(&srf->res); |
790 | ret = ttm_base_object_init(tfile, &user_srf->base, |
818 | ret = ttm_prime_object_init(tfile, res->backup_size, &user_srf->prime, |
791 | req->shareable, VMW_RES_SURFACE, |
819 | req->shareable, VMW_RES_SURFACE, |
Line 792... | Line 820... | ||
792 | &vmw_user_surface_base_release, NULL); |
820 | &vmw_user_surface_base_release, NULL); |
793 | 821 | ||
794 | if (unlikely(ret != 0)) { |
822 | if (unlikely(ret != 0)) { |
795 | vmw_resource_unreference(&tmp); |
823 | vmw_resource_unreference(&tmp); |
796 | vmw_resource_unreference(&res); |
824 | vmw_resource_unreference(&res); |
Line 797... | Line 825... | ||
797 | goto out_unlock; |
825 | goto out_unlock; |
798 | } |
826 | } |
Line 799... | Line 827... | ||
799 | 827 | ||
800 | rep->sid = user_srf->base.hash.key; |
828 | rep->sid = user_srf->prime.base.hash.key; |
801 | vmw_resource_unreference(&res); |
829 | vmw_resource_unreference(&res); |
802 | 830 | ||
803 | ttm_read_unlock(&vmaster->lock); |
831 | ttm_read_unlock(&vmaster->lock); |
804 | return 0; |
832 | return 0; |
805 | out_no_copy: |
833 | out_no_copy: |
806 | kfree(srf->offsets); |
834 | kfree(srf->offsets); |
807 | out_no_offsets: |
835 | out_no_offsets: |
808 | kfree(srf->sizes); |
836 | kfree(srf->sizes); |
809 | out_no_sizes: |
837 | out_no_sizes: |
810 | ttm_base_object_kfree(user_srf, base); |
838 | ttm_prime_object_kfree(user_srf, prime); |
811 | out_no_user_srf: |
839 | out_no_user_srf: |
Line 824... | Line 852... | ||
824 | * @file_priv: Pointer to a drm file private structure. |
852 | * @file_priv: Pointer to a drm file private structure. |
825 | */ |
853 | */ |
826 | int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, |
854 | int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, |
827 | struct drm_file *file_priv) |
855 | struct drm_file *file_priv) |
828 | { |
856 | { |
- | 857 | struct vmw_private *dev_priv = vmw_priv(dev); |
|
829 | union drm_vmw_surface_reference_arg *arg = |
858 | union drm_vmw_surface_reference_arg *arg = |
830 | (union drm_vmw_surface_reference_arg *)data; |
859 | (union drm_vmw_surface_reference_arg *)data; |
831 | struct drm_vmw_surface_arg *req = &arg->req; |
860 | struct drm_vmw_surface_arg *req = &arg->req; |
832 | struct drm_vmw_surface_create_req *rep = &arg->rep; |
861 | struct drm_vmw_surface_create_req *rep = &arg->rep; |
833 | struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; |
862 | struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; |
Line 835... | Line 864... | ||
835 | struct vmw_user_surface *user_srf; |
864 | struct vmw_user_surface *user_srf; |
836 | struct drm_vmw_size __user *user_sizes; |
865 | struct drm_vmw_size __user *user_sizes; |
837 | struct ttm_base_object *base; |
866 | struct ttm_base_object *base; |
838 | int ret = -EINVAL; |
867 | int ret = -EINVAL; |
Line 839... | Line 868... | ||
839 | 868 | ||
840 | base = ttm_base_object_lookup(tfile, req->sid); |
869 | base = ttm_base_object_lookup_for_ref(dev_priv->tdev, req->sid); |
841 | if (unlikely(base == NULL)) { |
870 | if (unlikely(base == NULL)) { |
842 | DRM_ERROR("Could not find surface to reference.\n"); |
871 | DRM_ERROR("Could not find surface to reference.\n"); |
843 | return -EINVAL; |
872 | return -EINVAL; |
Line 844... | Line 873... | ||
844 | } |
873 | } |
845 | 874 | ||
Line 846... | Line 875... | ||
846 | if (unlikely(base->object_type != VMW_RES_SURFACE)) |
875 | if (unlikely(ttm_base_object_type(base) != VMW_RES_SURFACE)) |
847 | goto out_bad_resource; |
876 | goto out_bad_resource; |
Line 848... | Line 877... | ||
848 | 877 | ||
- | 878 | user_srf = container_of(base, struct vmw_user_surface, prime.base); |
|
849 | user_srf = container_of(base, struct vmw_user_surface, base); |
879 | srf = &user_srf->srf; |
850 | srf = &user_srf->srf; |
880 | |
851 | 881 | ret = ttm_ref_object_add(tfile, &user_srf->prime.base, |
|
852 | ret = ttm_ref_object_add(tfile, &user_srf->base, TTM_REF_USAGE, NULL); |
882 | TTM_REF_USAGE, NULL); |