38,10 → 38,9 |
* @size: TTM accounting size for the surface. |
*/ |
struct vmw_user_surface { |
struct ttm_base_object base; |
struct ttm_prime_object prime; |
struct vmw_surface srf; |
uint32_t size; |
uint32_t backup_handle; |
}; |
|
/** |
68,7 → 67,15 |
struct ttm_validate_buffer *val_buf); |
static int vmw_legacy_srf_create(struct vmw_resource *res); |
static int vmw_legacy_srf_destroy(struct vmw_resource *res); |
static int vmw_gb_surface_create(struct vmw_resource *res); |
static int vmw_gb_surface_bind(struct vmw_resource *res, |
struct ttm_validate_buffer *val_buf); |
static int vmw_gb_surface_unbind(struct vmw_resource *res, |
bool readback, |
struct ttm_validate_buffer *val_buf); |
static int vmw_gb_surface_destroy(struct vmw_resource *res); |
|
|
static const struct vmw_user_resource_conv user_surface_conv = { |
.object_type = VMW_RES_SURFACE, |
.base_obj_to_res = vmw_user_surface_base_to_res, |
93,6 → 100,18 |
.unbind = &vmw_legacy_srf_unbind |
}; |
|
static const struct vmw_res_func vmw_gb_surface_func = { |
.res_type = vmw_res_surface, |
.needs_backup = true, |
.may_evict = true, |
.type_name = "guest backed surfaces", |
.backup_placement = &vmw_mob_placement, |
.create = vmw_gb_surface_create, |
.destroy = vmw_gb_surface_destroy, |
.bind = vmw_gb_surface_bind, |
.unbind = vmw_gb_surface_unbind |
}; |
|
/** |
* struct vmw_surface_dma - SVGA3D DMA command |
*/ |
291,6 → 310,11 |
struct vmw_surface *srf; |
void *cmd; |
|
if (res->func->destroy == vmw_gb_surface_destroy) { |
(void) vmw_gb_surface_destroy(res); |
return; |
} |
|
if (res->id != -1) { |
|
cmd = vmw_fifo_reserve(dev_priv, vmw_surface_destroy_size()); |
549,11 → 573,14 |
struct vmw_resource *res = &srf->res; |
|
BUG_ON(res_free == NULL); |
if (!dev_priv->has_mob) |
(void) vmw_3d_resource_inc(dev_priv, false); |
ret = vmw_resource_init(dev_priv, res, true, res_free, |
(dev_priv->has_mob) ? &vmw_gb_surface_func : |
&vmw_legacy_surface_func); |
|
if (unlikely(ret != 0)) { |
if (!dev_priv->has_mob) |
vmw_3d_resource_dec(dev_priv, false); |
res_free(res); |
return ret; |
580,7 → 607,8 |
static struct vmw_resource * |
vmw_user_surface_base_to_res(struct ttm_base_object *base) |
{ |
return &(container_of(base, struct vmw_user_surface, base)->srf.res); |
return &(container_of(base, struct vmw_user_surface, |
prime.base)->srf.res); |
} |
|
/** |
616,7 → 644,7 |
{ |
struct ttm_base_object *base = *p_base; |
struct vmw_user_surface *user_srf = |
container_of(base, struct vmw_user_surface, base); |
container_of(base, struct vmw_user_surface, prime.base); |
struct vmw_resource *res = &user_srf->srf.res; |
|
*p_base = NULL; |
733,7 → 761,7 |
|
srf->base_size = *srf->sizes; |
srf->autogen_filter = SVGA3D_TEX_FILTER_NONE; |
srf->multisample_count = 1; |
srf->multisample_count = 0; |
|
cur_bo_offset = 0; |
cur_offset = srf->offsets; |
774,8 → 802,8 |
} |
srf->snooper.crtc = NULL; |
|
user_srf->base.shareable = false; |
user_srf->base.tfile = NULL; |
user_srf->prime.base.shareable = false; |
user_srf->prime.base.tfile = NULL; |
|
/** |
* From this point, the generic resource management functions |
787,7 → 815,7 |
goto out_unlock; |
|
tmp = vmw_resource_reference(&srf->res); |
ret = ttm_base_object_init(tfile, &user_srf->base, |
ret = ttm_prime_object_init(tfile, res->backup_size, &user_srf->prime, |
req->shareable, VMW_RES_SURFACE, |
&vmw_user_surface_base_release, NULL); |
|
797,7 → 825,7 |
goto out_unlock; |
} |
|
rep->sid = user_srf->base.hash.key; |
rep->sid = user_srf->prime.base.hash.key; |
vmw_resource_unreference(&res); |
|
ttm_read_unlock(&vmaster->lock); |
807,7 → 835,7 |
out_no_offsets: |
kfree(srf->sizes); |
out_no_sizes: |
ttm_base_object_kfree(user_srf, base); |
ttm_prime_object_kfree(user_srf, prime); |
out_no_user_srf: |
ttm_mem_global_free(vmw_mem_glob(dev_priv), size); |
out_unlock: |
826,6 → 854,7 |
int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, |
struct drm_file *file_priv) |
{ |
struct vmw_private *dev_priv = vmw_priv(dev); |
union drm_vmw_surface_reference_arg *arg = |
(union drm_vmw_surface_reference_arg *)data; |
struct drm_vmw_surface_arg *req = &arg->req; |
837,19 → 866,20 |
struct ttm_base_object *base; |
int ret = -EINVAL; |
|
base = ttm_base_object_lookup(tfile, req->sid); |
base = ttm_base_object_lookup_for_ref(dev_priv->tdev, req->sid); |
if (unlikely(base == NULL)) { |
DRM_ERROR("Could not find surface to reference.\n"); |
return -EINVAL; |
} |
|
if (unlikely(base->object_type != VMW_RES_SURFACE)) |
if (unlikely(ttm_base_object_type(base) != VMW_RES_SURFACE)) |
goto out_bad_resource; |
|
user_srf = container_of(base, struct vmw_user_surface, base); |
user_srf = container_of(base, struct vmw_user_surface, prime.base); |
srf = &user_srf->srf; |
|
ret = ttm_ref_object_add(tfile, &user_srf->base, TTM_REF_USAGE, NULL); |
ret = ttm_ref_object_add(tfile, &user_srf->prime.base, |
TTM_REF_USAGE, NULL); |
if (unlikely(ret != 0)) { |
DRM_ERROR("Could not add a reference to a surface.\n"); |
goto out_no_reference; |