Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 269715
b: refs/heads/master
c: 2fcd5a7
h: refs/heads/master
i:
  269713: 6ba5a6d
  269711: f861bef
v: v3
  • Loading branch information
Jakob Bornecrantz authored and Dave Airlie committed Oct 5, 2011
1 parent 3abb435 commit e3e941d
Show file tree
Hide file tree
Showing 7 changed files with 441 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 44031d25ccface0ae647d664347ae3d3a8016f5f
refs/heads/master: 2fcd5a73bfd5341876f9ea6b5adcc1dd814226d4
13 changes: 13 additions & 0 deletions trunk/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@
#define DRM_IOCTL_VMW_FENCE_UNREF \
DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_FENCE_UNREF, \
struct drm_vmw_fence_arg)
#define DRM_IOCTL_VMW_PRESENT \
DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_PRESENT, \
struct drm_vmw_present_arg)
#define DRM_IOCTL_VMW_PRESENT_READBACK \
DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_PRESENT_READBACK, \
struct drm_vmw_present_readback_arg)

/**
* The core DRM version of this macro doesn't account for
Expand Down Expand Up @@ -146,6 +152,13 @@ static struct drm_ioctl_desc vmw_ioctls[] = {
DRM_AUTH | DRM_UNLOCKED),
VMW_IOCTL_DEF(VMW_GET_3D_CAP, vmw_get_cap_3d_ioctl,
DRM_AUTH | DRM_UNLOCKED),

/* these allow direct access to the framebuffers mark as master only */
VMW_IOCTL_DEF(VMW_PRESENT, vmw_present_ioctl,
DRM_MASTER | DRM_AUTH | DRM_UNLOCKED),
VMW_IOCTL_DEF(VMW_PRESENT_READBACK,
vmw_present_readback_ioctl,
DRM_MASTER | DRM_AUTH | DRM_UNLOCKED),
};

static struct pci_device_id vmw_pci_id_list[] = {
Expand Down
19 changes: 19 additions & 0 deletions trunk/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ struct vmw_cursor_snooper {
uint32_t *image;
};

struct vmw_framebuffer;

struct vmw_surface {
struct vmw_resource res;
uint32_t flags;
Expand Down Expand Up @@ -430,6 +432,10 @@ extern int vmw_getparam_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int vmw_present_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int vmw_present_readback_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);

/**
* Fifo utilities - vmwgfx_fifo.c
Expand Down Expand Up @@ -554,6 +560,19 @@ bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv,
uint32_t pitch,
uint32_t height);
u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc);
int vmw_kms_present(struct vmw_private *dev_priv,
struct drm_file *file_priv,
struct vmw_framebuffer *vfb,
struct vmw_surface *surface,
uint32_t sid, int32_t destX, int32_t destY,
struct drm_vmw_rect *clips,
uint32_t num_clips);
int vmw_kms_readback(struct vmw_private *dev_priv,
struct drm_file *file_priv,
struct vmw_framebuffer *vfb,
struct drm_vmw_fence_rep __user *user_fence_rep,
struct drm_vmw_rect *clips,
uint32_t num_clips);

/**
* Overlay control - vmwgfx_overlay.c
Expand Down
172 changes: 172 additions & 0 deletions trunk/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include "vmwgfx_drv.h"
#include "vmwgfx_drm.h"
#include "vmwgfx_kms.h"

int vmw_getparam_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
Expand Down Expand Up @@ -110,3 +111,174 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data,

return ret;
}

int vmw_present_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
struct vmw_private *dev_priv = vmw_priv(dev);
struct drm_vmw_present_arg *arg =
(struct drm_vmw_present_arg *)data;
struct vmw_surface *surface;
struct vmw_master *vmaster = vmw_master(file_priv->master);
struct drm_vmw_rect __user *clips_ptr;
struct drm_vmw_rect *clips = NULL;
struct drm_mode_object *obj;
struct vmw_framebuffer *vfb;
uint32_t num_clips;
int ret;

num_clips = arg->num_clips;
clips_ptr = (struct drm_vmw_rect *)(unsigned long)arg->clips_ptr;

if (unlikely(num_clips == 0))
return 0;

if (clips_ptr == NULL) {
DRM_ERROR("Variable clips_ptr must be specified.\n");
ret = -EINVAL;
goto out_clips;
}

clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL);
if (clips == NULL) {
DRM_ERROR("Failed to allocate clip rect list.\n");
ret = -ENOMEM;
goto out_clips;
}

ret = copy_from_user(clips, clips_ptr, num_clips * sizeof(*clips));
if (ret) {
DRM_ERROR("Failed to copy clip rects from userspace.\n");
goto out_no_copy;
}

ret = mutex_lock_interruptible(&dev->mode_config.mutex);
if (unlikely(ret != 0)) {
ret = -ERESTARTSYS;
goto out_no_mode_mutex;
}

obj = drm_mode_object_find(dev, arg->fb_id, DRM_MODE_OBJECT_FB);
if (!obj) {
DRM_ERROR("Invalid framebuffer id.\n");
ret = -EINVAL;
goto out_no_fb;
}

vfb = vmw_framebuffer_to_vfb(obj_to_fb(obj));
if (!vfb->dmabuf) {
DRM_ERROR("Framebuffer not dmabuf backed.\n");
ret = -EINVAL;
goto out_no_fb;
}

ret = ttm_read_lock(&vmaster->lock, true);
if (unlikely(ret != 0))
goto out_no_ttm_lock;

ret = vmw_user_surface_lookup_handle(dev_priv, tfile, arg->sid,
&surface);
if (ret)
goto out_no_surface;

ret = vmw_kms_present(dev_priv, file_priv,
vfb, surface, arg->sid,
arg->dest_x, arg->dest_y,
clips, num_clips);

/* vmw_user_surface_lookup takes one ref so does new_fb */
vmw_surface_unreference(&surface);

out_no_surface:
ttm_read_unlock(&vmaster->lock);
out_no_ttm_lock:
out_no_fb:
mutex_unlock(&dev->mode_config.mutex);
out_no_mode_mutex:
out_no_copy:
kfree(clips);
out_clips:
return ret;
}

int vmw_present_readback_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct vmw_private *dev_priv = vmw_priv(dev);
struct drm_vmw_present_readback_arg *arg =
(struct drm_vmw_present_readback_arg *)data;
struct drm_vmw_fence_rep __user *user_fence_rep =
(struct drm_vmw_fence_rep __user *)
(unsigned long)arg->fence_rep;
struct vmw_master *vmaster = vmw_master(file_priv->master);
struct drm_vmw_rect __user *clips_ptr;
struct drm_vmw_rect *clips = NULL;
struct drm_mode_object *obj;
struct vmw_framebuffer *vfb;
uint32_t num_clips;
int ret;

num_clips = arg->num_clips;
clips_ptr = (struct drm_vmw_rect *)(unsigned long)arg->clips_ptr;

if (unlikely(num_clips == 0))
return 0;

if (clips_ptr == NULL) {
DRM_ERROR("Argument clips_ptr must be specified.\n");
ret = -EINVAL;
goto out_clips;
}

clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL);
if (clips == NULL) {
DRM_ERROR("Failed to allocate clip rect list.\n");
ret = -ENOMEM;
goto out_clips;
}

ret = copy_from_user(clips, clips_ptr, num_clips * sizeof(*clips));
if (ret) {
DRM_ERROR("Failed to copy clip rects from userspace.\n");
goto out_no_copy;
}

ret = mutex_lock_interruptible(&dev->mode_config.mutex);
if (unlikely(ret != 0)) {
ret = -ERESTARTSYS;
goto out_no_mode_mutex;
}

obj = drm_mode_object_find(dev, arg->fb_id, DRM_MODE_OBJECT_FB);
if (!obj) {
DRM_ERROR("Invalid framebuffer id.\n");
ret = -EINVAL;
goto out_no_fb;
}

vfb = vmw_framebuffer_to_vfb(obj_to_fb(obj));
if (!vfb->dmabuf) {
DRM_ERROR("Framebuffer not dmabuf backed.\n");
ret = -EINVAL;
goto out_no_fb;
}

ret = ttm_read_lock(&vmaster->lock, true);
if (unlikely(ret != 0))
goto out_no_ttm_lock;

ret = vmw_kms_readback(dev_priv, file_priv,
vfb, user_fence_rep,
clips, num_clips);

ttm_read_unlock(&vmaster->lock);
out_no_ttm_lock:
out_no_fb:
mutex_unlock(&dev->mode_config.mutex);
out_no_mode_mutex:
out_no_copy:
kfree(clips);
out_clips:
return ret;
}
Loading

0 comments on commit e3e941d

Please sign in to comment.