int qxl_gem_object_create_with_handle(struct qxl_device *qdev, struct drm_file *file_priv, u32 domain, size_t size, struct qxl_surface *surf, struct qxl_bo **qobj, uint32_t *handle) { struct drm_gem_object *gobj; int r; BUG_ON(!qobj); BUG_ON(!handle); r = qxl_gem_object_create(qdev, size, 0, domain, false, false, surf, &gobj); if (r) return -ENOMEM; r = drm_gem_handle_create(file_priv, gobj, handle); if (r) return r; /* drop reference from allocate - handle holds it now */ *qobj = gem_to_qxl_bo(gobj); drm_gem_object_unreference_unlocked(gobj); return 0; }
static int qxlfb_create_pinned_object(struct qxl_fbdev *qfbdev, const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **gobj_p) { struct qxl_device *qdev = qfbdev->qdev; struct drm_gem_object *gobj = NULL; struct qxl_bo *qbo = NULL; int ret; int aligned_size, size; int height = mode_cmd->height; int bpp; int depth; drm_fb_get_bpp_depth(mode_cmd->pixel_format, &bpp, &depth); size = mode_cmd->pitches[0] * height; aligned_size = ALIGN(size, PAGE_SIZE); /* TODO: unallocate and reallocate surface0 for real. Hack to just * have a large enough surface0 for 1024x768 Xorg 32bpp mode */ ret = qxl_gem_object_create(qdev, aligned_size, 0, QXL_GEM_DOMAIN_SURFACE, false, /* is discardable */ false, /* is kernel (false means device) */ NULL, &gobj); if (ret) { pr_err("failed to allocate framebuffer (%d)\n", aligned_size); return -ENOMEM; } qbo = gem_to_qxl_bo(gobj); qbo->surf.width = mode_cmd->width; qbo->surf.height = mode_cmd->height; qbo->surf.stride = mode_cmd->pitches[0]; qbo->surf.format = SPICE_SURFACE_FMT_32_xRGB; ret = qxl_bo_reserve(qbo, false); if (unlikely(ret != 0)) goto out_unref; ret = qxl_bo_pin(qbo, QXL_GEM_DOMAIN_SURFACE, NULL); if (ret) { qxl_bo_unreserve(qbo); goto out_unref; } ret = qxl_bo_kmap(qbo, NULL); qxl_bo_unreserve(qbo); /* unreserve, will be mmaped */ if (ret) goto out_unref; *gobj_p = gobj; return 0; out_unref: qxlfb_destroy_pinned_object(gobj); *gobj_p = NULL; return ret; }
int qxl_create_monitors_object(struct qxl_device *qdev) { int ret; struct drm_gem_object *gobj; int max_allowed = qxl_num_crtc; int monitors_config_size = sizeof(struct qxl_monitors_config) + max_allowed * sizeof(struct qxl_head); ret = qxl_gem_object_create(qdev, monitors_config_size, 0, QXL_GEM_DOMAIN_VRAM, false, false, NULL, &gobj); if (ret) { DRM_ERROR("%s: failed to create gem ret=%d\n", __func__, ret); return -ENOMEM; } qdev->monitors_config_bo = gem_to_qxl_bo(gobj); ret = qxl_bo_reserve(qdev->monitors_config_bo, false); if (ret) return ret; ret = qxl_bo_pin(qdev->monitors_config_bo, QXL_GEM_DOMAIN_VRAM, NULL); if (ret) { qxl_bo_unreserve(qdev->monitors_config_bo); return ret; } qxl_bo_unreserve(qdev->monitors_config_bo); qxl_bo_kmap(qdev->monitors_config_bo, NULL); qdev->monitors_config = qdev->monitors_config_bo->kptr; qdev->ram_header->monitors_config = qxl_bo_physical_address(qdev, qdev->monitors_config_bo, 0); memset(qdev->monitors_config, 0, monitors_config_size); qdev->monitors_config->max_allowed = max_allowed; return 0; }