diff options
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 172 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 170 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 3 | ||||
-rw-r--r-- | include/drm/vmwgfx_drm.h | 63 |
6 files changed, 440 insertions, 0 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 73757c3db8eb..ace4402214c6 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -94,6 +94,12 @@ | |||
94 | #define DRM_IOCTL_VMW_FENCE_UNREF \ | 94 | #define DRM_IOCTL_VMW_FENCE_UNREF \ |
95 | DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_FENCE_UNREF, \ | 95 | DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_FENCE_UNREF, \ |
96 | struct drm_vmw_fence_arg) | 96 | struct drm_vmw_fence_arg) |
97 | #define DRM_IOCTL_VMW_PRESENT \ | ||
98 | DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_PRESENT, \ | ||
99 | struct drm_vmw_present_arg) | ||
100 | #define DRM_IOCTL_VMW_PRESENT_READBACK \ | ||
101 | DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_PRESENT_READBACK, \ | ||
102 | struct drm_vmw_present_readback_arg) | ||
97 | 103 | ||
98 | /** | 104 | /** |
99 | * The core DRM version of this macro doesn't account for | 105 | * The core DRM version of this macro doesn't account for |
@@ -146,6 +152,13 @@ static struct drm_ioctl_desc vmw_ioctls[] = { | |||
146 | DRM_AUTH | DRM_UNLOCKED), | 152 | DRM_AUTH | DRM_UNLOCKED), |
147 | VMW_IOCTL_DEF(VMW_GET_3D_CAP, vmw_get_cap_3d_ioctl, | 153 | VMW_IOCTL_DEF(VMW_GET_3D_CAP, vmw_get_cap_3d_ioctl, |
148 | DRM_AUTH | DRM_UNLOCKED), | 154 | DRM_AUTH | DRM_UNLOCKED), |
155 | |||
156 | /* these allow direct access to the framebuffers mark as master only */ | ||
157 | VMW_IOCTL_DEF(VMW_PRESENT, vmw_present_ioctl, | ||
158 | DRM_MASTER | DRM_AUTH | DRM_UNLOCKED), | ||
159 | VMW_IOCTL_DEF(VMW_PRESENT_READBACK, | ||
160 | vmw_present_readback_ioctl, | ||
161 | DRM_MASTER | DRM_AUTH | DRM_UNLOCKED), | ||
149 | }; | 162 | }; |
150 | 163 | ||
151 | static struct pci_device_id vmw_pci_id_list[] = { | 164 | static struct pci_device_id vmw_pci_id_list[] = { |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 2124fbc919aa..fc0e3bc63ec0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -97,6 +97,8 @@ struct vmw_cursor_snooper { | |||
97 | uint32_t *image; | 97 | uint32_t *image; |
98 | }; | 98 | }; |
99 | 99 | ||
100 | struct vmw_framebuffer; | ||
101 | |||
100 | struct vmw_surface { | 102 | struct vmw_surface { |
101 | struct vmw_resource res; | 103 | struct vmw_resource res; |
102 | uint32_t flags; | 104 | uint32_t flags; |
@@ -430,6 +432,10 @@ extern int vmw_getparam_ioctl(struct drm_device *dev, void *data, | |||
430 | struct drm_file *file_priv); | 432 | struct drm_file *file_priv); |
431 | extern int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, | 433 | extern int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, |
432 | struct drm_file *file_priv); | 434 | struct drm_file *file_priv); |
435 | extern int vmw_present_ioctl(struct drm_device *dev, void *data, | ||
436 | struct drm_file *file_priv); | ||
437 | extern int vmw_present_readback_ioctl(struct drm_device *dev, void *data, | ||
438 | struct drm_file *file_priv); | ||
433 | 439 | ||
434 | /** | 440 | /** |
435 | * Fifo utilities - vmwgfx_fifo.c | 441 | * Fifo utilities - vmwgfx_fifo.c |
@@ -554,6 +560,19 @@ bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv, | |||
554 | uint32_t pitch, | 560 | uint32_t pitch, |
555 | uint32_t height); | 561 | uint32_t height); |
556 | u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc); | 562 | u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc); |
563 | int vmw_kms_present(struct vmw_private *dev_priv, | ||
564 | struct drm_file *file_priv, | ||
565 | struct vmw_framebuffer *vfb, | ||
566 | struct vmw_surface *surface, | ||
567 | uint32_t sid, int32_t destX, int32_t destY, | ||
568 | struct drm_vmw_rect *clips, | ||
569 | uint32_t num_clips); | ||
570 | int vmw_kms_readback(struct vmw_private *dev_priv, | ||
571 | struct drm_file *file_priv, | ||
572 | struct vmw_framebuffer *vfb, | ||
573 | struct drm_vmw_fence_rep __user *user_fence_rep, | ||
574 | struct drm_vmw_rect *clips, | ||
575 | uint32_t num_clips); | ||
557 | 576 | ||
558 | /** | 577 | /** |
559 | * Overlay control - vmwgfx_overlay.c | 578 | * Overlay control - vmwgfx_overlay.c |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 5ecf96660644..c0284a4784c9 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | #include "vmwgfx_drv.h" | 28 | #include "vmwgfx_drv.h" |
29 | #include "vmwgfx_drm.h" | 29 | #include "vmwgfx_drm.h" |
30 | #include "vmwgfx_kms.h" | ||
30 | 31 | ||
31 | int vmw_getparam_ioctl(struct drm_device *dev, void *data, | 32 | int vmw_getparam_ioctl(struct drm_device *dev, void *data, |
32 | struct drm_file *file_priv) | 33 | struct drm_file *file_priv) |
@@ -110,3 +111,174 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, | |||
110 | 111 | ||
111 | return ret; | 112 | return ret; |
112 | } | 113 | } |
114 | |||
115 | int vmw_present_ioctl(struct drm_device *dev, void *data, | ||
116 | struct drm_file *file_priv) | ||
117 | { | ||
118 | struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; | ||
119 | struct vmw_private *dev_priv = vmw_priv(dev); | ||
120 | struct drm_vmw_present_arg *arg = | ||
121 | (struct drm_vmw_present_arg *)data; | ||
122 | struct vmw_surface *surface; | ||
123 | struct vmw_master *vmaster = vmw_master(file_priv->master); | ||
124 | struct drm_vmw_rect __user *clips_ptr; | ||
125 | struct drm_vmw_rect *clips = NULL; | ||
126 | struct drm_mode_object *obj; | ||
127 | struct vmw_framebuffer *vfb; | ||
128 | uint32_t num_clips; | ||
129 | int ret; | ||
130 | |||
131 | num_clips = arg->num_clips; | ||
132 | clips_ptr = (struct drm_vmw_rect *)(unsigned long)arg->clips_ptr; | ||
133 | |||
134 | if (unlikely(num_clips == 0)) | ||
135 | return 0; | ||
136 | |||
137 | if (clips_ptr == NULL) { | ||
138 | DRM_ERROR("Variable clips_ptr must be specified.\n"); | ||
139 | ret = -EINVAL; | ||
140 | goto out_clips; | ||
141 | } | ||
142 | |||
143 | clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); | ||
144 | if (clips == NULL) { | ||
145 | DRM_ERROR("Failed to allocate clip rect list.\n"); | ||
146 | ret = -ENOMEM; | ||
147 | goto out_clips; | ||
148 | } | ||
149 | |||
150 | ret = copy_from_user(clips, clips_ptr, num_clips * sizeof(*clips)); | ||
151 | if (ret) { | ||
152 | DRM_ERROR("Failed to copy clip rects from userspace.\n"); | ||
153 | goto out_no_copy; | ||
154 | } | ||
155 | |||
156 | ret = mutex_lock_interruptible(&dev->mode_config.mutex); | ||
157 | if (unlikely(ret != 0)) { | ||
158 | ret = -ERESTARTSYS; | ||
159 | goto out_no_mode_mutex; | ||
160 | } | ||
161 | |||
162 | obj = drm_mode_object_find(dev, arg->fb_id, DRM_MODE_OBJECT_FB); | ||
163 | if (!obj) { | ||
164 | DRM_ERROR("Invalid framebuffer id.\n"); | ||
165 | ret = -EINVAL; | ||
166 | goto out_no_fb; | ||
167 | } | ||
168 | |||
169 | vfb = vmw_framebuffer_to_vfb(obj_to_fb(obj)); | ||
170 | if (!vfb->dmabuf) { | ||
171 | DRM_ERROR("Framebuffer not dmabuf backed.\n"); | ||
172 | ret = -EINVAL; | ||
173 | goto out_no_fb; | ||
174 | } | ||
175 | |||
176 | ret = ttm_read_lock(&vmaster->lock, true); | ||
177 | if (unlikely(ret != 0)) | ||
178 | goto out_no_ttm_lock; | ||
179 | |||
180 | ret = vmw_user_surface_lookup_handle(dev_priv, tfile, arg->sid, | ||
181 | &surface); | ||
182 | if (ret) | ||
183 | goto out_no_surface; | ||
184 | |||
185 | ret = vmw_kms_present(dev_priv, file_priv, | ||
186 | vfb, surface, arg->sid, | ||
187 | arg->dest_x, arg->dest_y, | ||
188 | clips, num_clips); | ||
189 | |||
190 | /* vmw_user_surface_lookup takes one ref so does new_fb */ | ||
191 | vmw_surface_unreference(&surface); | ||
192 | |||
193 | out_no_surface: | ||
194 | ttm_read_unlock(&vmaster->lock); | ||
195 | out_no_ttm_lock: | ||
196 | out_no_fb: | ||
197 | mutex_unlock(&dev->mode_config.mutex); | ||
198 | out_no_mode_mutex: | ||
199 | out_no_copy: | ||
200 | kfree(clips); | ||
201 | out_clips: | ||
202 | return ret; | ||
203 | } | ||
204 | |||
205 | int vmw_present_readback_ioctl(struct drm_device *dev, void *data, | ||
206 | struct drm_file *file_priv) | ||
207 | { | ||
208 | struct vmw_private *dev_priv = vmw_priv(dev); | ||
209 | struct drm_vmw_present_readback_arg *arg = | ||
210 | (struct drm_vmw_present_readback_arg *)data; | ||
211 | struct drm_vmw_fence_rep __user *user_fence_rep = | ||
212 | (struct drm_vmw_fence_rep __user *) | ||
213 | (unsigned long)arg->fence_rep; | ||
214 | struct vmw_master *vmaster = vmw_master(file_priv->master); | ||
215 | struct drm_vmw_rect __user *clips_ptr; | ||
216 | struct drm_vmw_rect *clips = NULL; | ||
217 | struct drm_mode_object *obj; | ||
218 | struct vmw_framebuffer *vfb; | ||
219 | uint32_t num_clips; | ||
220 | int ret; | ||
221 | |||
222 | num_clips = arg->num_clips; | ||
223 | clips_ptr = (struct drm_vmw_rect *)(unsigned long)arg->clips_ptr; | ||
224 | |||
225 | if (unlikely(num_clips == 0)) | ||
226 | return 0; | ||
227 | |||
228 | if (clips_ptr == NULL) { | ||
229 | DRM_ERROR("Argument clips_ptr must be specified.\n"); | ||
230 | ret = -EINVAL; | ||
231 | goto out_clips; | ||
232 | } | ||
233 | |||
234 | clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); | ||
235 | if (clips == NULL) { | ||
236 | DRM_ERROR("Failed to allocate clip rect list.\n"); | ||
237 | ret = -ENOMEM; | ||
238 | goto out_clips; | ||
239 | } | ||
240 | |||
241 | ret = copy_from_user(clips, clips_ptr, num_clips * sizeof(*clips)); | ||
242 | if (ret) { | ||
243 | DRM_ERROR("Failed to copy clip rects from userspace.\n"); | ||
244 | goto out_no_copy; | ||
245 | } | ||
246 | |||
247 | ret = mutex_lock_interruptible(&dev->mode_config.mutex); | ||
248 | if (unlikely(ret != 0)) { | ||
249 | ret = -ERESTARTSYS; | ||
250 | goto out_no_mode_mutex; | ||
251 | } | ||
252 | |||
253 | obj = drm_mode_object_find(dev, arg->fb_id, DRM_MODE_OBJECT_FB); | ||
254 | if (!obj) { | ||
255 | DRM_ERROR("Invalid framebuffer id.\n"); | ||
256 | ret = -EINVAL; | ||
257 | goto out_no_fb; | ||
258 | } | ||
259 | |||
260 | vfb = vmw_framebuffer_to_vfb(obj_to_fb(obj)); | ||
261 | if (!vfb->dmabuf) { | ||
262 | DRM_ERROR("Framebuffer not dmabuf backed.\n"); | ||
263 | ret = -EINVAL; | ||
264 | goto out_no_fb; | ||
265 | } | ||
266 | |||
267 | ret = ttm_read_lock(&vmaster->lock, true); | ||
268 | if (unlikely(ret != 0)) | ||
269 | goto out_no_ttm_lock; | ||
270 | |||
271 | ret = vmw_kms_readback(dev_priv, file_priv, | ||
272 | vfb, user_fence_rep, | ||
273 | clips, num_clips); | ||
274 | |||
275 | ttm_read_unlock(&vmaster->lock); | ||
276 | out_no_ttm_lock: | ||
277 | out_no_fb: | ||
278 | mutex_unlock(&dev->mode_config.mutex); | ||
279 | out_no_mode_mutex: | ||
280 | out_no_copy: | ||
281 | kfree(clips); | ||
282 | out_clips: | ||
283 | return ret; | ||
284 | } | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 8628bc7cc0d6..41916b58a3fb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -800,6 +800,7 @@ static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv, | |||
800 | vfbd->base.pin = vmw_framebuffer_dmabuf_pin; | 800 | vfbd->base.pin = vmw_framebuffer_dmabuf_pin; |
801 | vfbd->base.unpin = vmw_framebuffer_dmabuf_unpin; | 801 | vfbd->base.unpin = vmw_framebuffer_dmabuf_unpin; |
802 | } | 802 | } |
803 | vfbd->base.dmabuf = true; | ||
803 | vfbd->buffer = dmabuf; | 804 | vfbd->buffer = dmabuf; |
804 | vfbd->handle = mode_cmd->handle; | 805 | vfbd->handle = mode_cmd->handle; |
805 | *out = &vfbd->base; | 806 | *out = &vfbd->base; |
@@ -900,6 +901,175 @@ static struct drm_mode_config_funcs vmw_kms_funcs = { | |||
900 | .fb_create = vmw_kms_fb_create, | 901 | .fb_create = vmw_kms_fb_create, |
901 | }; | 902 | }; |
902 | 903 | ||
904 | int vmw_kms_present(struct vmw_private *dev_priv, | ||
905 | struct drm_file *file_priv, | ||
906 | struct vmw_framebuffer *vfb, | ||
907 | struct vmw_surface *surface, | ||
908 | uint32_t sid, | ||
909 | int32_t destX, int32_t destY, | ||
910 | struct drm_vmw_rect *clips, | ||
911 | uint32_t num_clips) | ||
912 | { | ||
913 | size_t fifo_size; | ||
914 | int i, ret; | ||
915 | |||
916 | struct { | ||
917 | SVGA3dCmdHeader header; | ||
918 | SVGA3dCmdBlitSurfaceToScreen body; | ||
919 | } *cmd; | ||
920 | SVGASignedRect *blits; | ||
921 | |||
922 | BUG_ON(surface == NULL); | ||
923 | BUG_ON(!clips || !num_clips); | ||
924 | |||
925 | fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num_clips; | ||
926 | cmd = kmalloc(fifo_size, GFP_KERNEL); | ||
927 | if (unlikely(cmd == NULL)) { | ||
928 | DRM_ERROR("Failed to allocate temporary fifo memory.\n"); | ||
929 | return -ENOMEM; | ||
930 | } | ||
931 | |||
932 | memset(cmd, 0, fifo_size); | ||
933 | |||
934 | cmd->header.id = cpu_to_le32(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN); | ||
935 | cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header)); | ||
936 | |||
937 | cmd->body.srcImage.sid = sid; | ||
938 | cmd->body.destScreenId = SVGA_ID_INVALID; /* virtual coords */ | ||
939 | |||
940 | cmd->body.srcRect.left = 0; | ||
941 | cmd->body.srcRect.right = surface->sizes[0].width; | ||
942 | cmd->body.srcRect.top = 0; | ||
943 | cmd->body.srcRect.bottom = surface->sizes[0].height; | ||
944 | |||
945 | cmd->body.destRect.left = destX; | ||
946 | cmd->body.destRect.right = destX + surface->sizes[0].width; | ||
947 | cmd->body.destRect.top = destY; | ||
948 | cmd->body.destRect.bottom = destY + surface->sizes[0].height; | ||
949 | |||
950 | blits = (SVGASignedRect *)&cmd[1]; | ||
951 | for (i = 0; i < num_clips; i++) { | ||
952 | blits[i].left = clips[i].x; | ||
953 | blits[i].right = clips[i].x + clips[i].w; | ||
954 | blits[i].top = clips[i].y; | ||
955 | blits[i].bottom = clips[i].y + clips[i].h; | ||
956 | } | ||
957 | |||
958 | ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, | ||
959 | fifo_size, 0, NULL); | ||
960 | |||
961 | kfree(cmd); | ||
962 | |||
963 | return ret; | ||
964 | } | ||
965 | |||
966 | int vmw_kms_readback(struct vmw_private *dev_priv, | ||
967 | struct drm_file *file_priv, | ||
968 | struct vmw_framebuffer *vfb, | ||
969 | struct drm_vmw_fence_rep __user *user_fence_rep, | ||
970 | struct drm_vmw_rect *clips, | ||
971 | uint32_t num_clips) | ||
972 | { | ||
973 | struct vmw_framebuffer_dmabuf *vfbd = | ||
974 | vmw_framebuffer_to_vfbd(&vfb->base); | ||
975 | struct vmw_dma_buffer *dmabuf = vfbd->buffer; | ||
976 | struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS]; | ||
977 | struct drm_crtc *crtc; | ||
978 | size_t fifo_size; | ||
979 | int i, k, ret, num_units, blits_pos; | ||
980 | |||
981 | struct { | ||
982 | uint32_t header; | ||
983 | SVGAFifoCmdDefineGMRFB body; | ||
984 | } *cmd; | ||
985 | struct { | ||
986 | uint32_t header; | ||
987 | SVGAFifoCmdBlitScreenToGMRFB body; | ||
988 | } *blits; | ||
989 | |||
990 | num_units = 0; | ||
991 | list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) { | ||
992 | if (crtc->fb != &vfb->base) | ||
993 | continue; | ||
994 | units[num_units++] = vmw_crtc_to_du(crtc); | ||
995 | } | ||
996 | |||
997 | BUG_ON(dmabuf == NULL); | ||
998 | BUG_ON(!clips || !num_clips); | ||
999 | |||
1000 | /* take a safe guess at fifo size */ | ||
1001 | fifo_size = sizeof(*cmd) + sizeof(*blits) * num_clips * num_units; | ||
1002 | cmd = kmalloc(fifo_size, GFP_KERNEL); | ||
1003 | if (unlikely(cmd == NULL)) { | ||
1004 | DRM_ERROR("Failed to allocate temporary fifo memory.\n"); | ||
1005 | return -ENOMEM; | ||
1006 | } | ||
1007 | |||
1008 | memset(cmd, 0, fifo_size); | ||
1009 | cmd->header = SVGA_CMD_DEFINE_GMRFB; | ||
1010 | cmd->body.format.bitsPerPixel = vfb->base.bits_per_pixel; | ||
1011 | cmd->body.format.colorDepth = vfb->base.depth; | ||
1012 | cmd->body.format.reserved = 0; | ||
1013 | cmd->body.bytesPerLine = vfb->base.pitch; | ||
1014 | cmd->body.ptr.gmrId = vfbd->handle; | ||
1015 | cmd->body.ptr.offset = 0; | ||
1016 | |||
1017 | blits = (void *)&cmd[1]; | ||
1018 | blits_pos = 0; | ||
1019 | for (i = 0; i < num_units; i++) { | ||
1020 | struct drm_vmw_rect *c = clips; | ||
1021 | for (k = 0; k < num_clips; k++, c++) { | ||
1022 | /* transform clip coords to crtc origin based coords */ | ||
1023 | int clip_x1 = c->x - units[i]->crtc.x; | ||
1024 | int clip_x2 = c->x - units[i]->crtc.x + c->w; | ||
1025 | int clip_y1 = c->y - units[i]->crtc.y; | ||
1026 | int clip_y2 = c->y - units[i]->crtc.y + c->h; | ||
1027 | int dest_x = c->x; | ||
1028 | int dest_y = c->y; | ||
1029 | |||
1030 | /* compensate for clipping, we negate | ||
1031 | * a negative number and add that. | ||
1032 | */ | ||
1033 | if (clip_x1 < 0) | ||
1034 | dest_x += -clip_x1; | ||
1035 | if (clip_y1 < 0) | ||
1036 | dest_y += -clip_y1; | ||
1037 | |||
1038 | /* clip */ | ||
1039 | clip_x1 = max(clip_x1, 0); | ||
1040 | clip_y1 = max(clip_y1, 0); | ||
1041 | clip_x2 = min(clip_x2, units[i]->crtc.mode.hdisplay); | ||
1042 | clip_y2 = min(clip_y2, units[i]->crtc.mode.vdisplay); | ||
1043 | |||
1044 | /* and cull any rects that misses the crtc */ | ||
1045 | if (clip_x1 >= units[i]->crtc.mode.hdisplay || | ||
1046 | clip_y1 >= units[i]->crtc.mode.vdisplay || | ||
1047 | clip_x2 <= 0 || clip_y2 <= 0) | ||
1048 | continue; | ||
1049 | |||
1050 | blits[blits_pos].header = SVGA_CMD_BLIT_SCREEN_TO_GMRFB; | ||
1051 | blits[blits_pos].body.srcScreenId = units[i]->unit; | ||
1052 | blits[blits_pos].body.destOrigin.x = dest_x; | ||
1053 | blits[blits_pos].body.destOrigin.y = dest_y; | ||
1054 | |||
1055 | blits[blits_pos].body.srcRect.left = clip_x1; | ||
1056 | blits[blits_pos].body.srcRect.top = clip_y1; | ||
1057 | blits[blits_pos].body.srcRect.right = clip_x2; | ||
1058 | blits[blits_pos].body.srcRect.bottom = clip_y2; | ||
1059 | blits_pos++; | ||
1060 | } | ||
1061 | } | ||
1062 | /* reset size here and use calculated exact size from loops */ | ||
1063 | fifo_size = sizeof(*cmd) + sizeof(*blits) * blits_pos; | ||
1064 | |||
1065 | ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, fifo_size, | ||
1066 | 0, user_fence_rep); | ||
1067 | |||
1068 | kfree(cmd); | ||
1069 | |||
1070 | return ret; | ||
1071 | } | ||
1072 | |||
903 | int vmw_kms_init(struct vmw_private *dev_priv) | 1073 | int vmw_kms_init(struct vmw_private *dev_priv) |
904 | { | 1074 | { |
905 | struct drm_device *dev = dev_priv->dev; | 1075 | struct drm_device *dev = dev_priv->dev; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index ee16a06e4ca1..08d2630ac3a7 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | |||
@@ -47,6 +47,7 @@ struct vmw_framebuffer { | |||
47 | struct drm_framebuffer base; | 47 | struct drm_framebuffer base; |
48 | int (*pin)(struct vmw_framebuffer *fb); | 48 | int (*pin)(struct vmw_framebuffer *fb); |
49 | int (*unpin)(struct vmw_framebuffer *fb); | 49 | int (*unpin)(struct vmw_framebuffer *fb); |
50 | bool dmabuf; | ||
50 | }; | 51 | }; |
51 | 52 | ||
52 | 53 | ||
@@ -95,6 +96,8 @@ struct vmw_display_unit { | |||
95 | struct drm_display_mode *pref_mode; | 96 | struct drm_display_mode *pref_mode; |
96 | }; | 97 | }; |
97 | 98 | ||
99 | #define vmw_crtc_to_du(x) \ | ||
100 | container_of(x, struct vmw_display_unit, crtc) | ||
98 | #define vmw_connector_to_du(x) \ | 101 | #define vmw_connector_to_du(x) \ |
99 | container_of(x, struct vmw_display_unit, connector) | 102 | container_of(x, struct vmw_display_unit, connector) |
100 | 103 | ||
diff --git a/include/drm/vmwgfx_drm.h b/include/drm/vmwgfx_drm.h index 29cd9cfdd611..5b5b0a891f36 100644 --- a/include/drm/vmwgfx_drm.h +++ b/include/drm/vmwgfx_drm.h | |||
@@ -52,6 +52,8 @@ | |||
52 | #define DRM_VMW_FENCE_SIGNALED 15 | 52 | #define DRM_VMW_FENCE_SIGNALED 15 |
53 | #define DRM_VMW_FENCE_UNREF 16 | 53 | #define DRM_VMW_FENCE_UNREF 16 |
54 | #define DRM_VMW_FENCE_EVENT 17 | 54 | #define DRM_VMW_FENCE_EVENT 17 |
55 | #define DRM_VMW_PRESENT 18 | ||
56 | #define DRM_VMW_PRESENT_READBACK 19 | ||
55 | 57 | ||
56 | 58 | ||
57 | /*************************************************************************/ | 59 | /*************************************************************************/ |
@@ -681,5 +683,66 @@ struct drm_vmw_fence_arg { | |||
681 | }; | 683 | }; |
682 | 684 | ||
683 | 685 | ||
686 | /*************************************************************************/ | ||
687 | /** | ||
688 | * DRM_VMW_PRESENT | ||
689 | * | ||
690 | * Executes an SVGA present on a given fb for a given surface. The surface | ||
691 | * is placed on the framebuffer. Cliprects are given relative to the given | ||
692 | * point (the point disignated by dest_{x|y}). | ||
693 | * | ||
694 | */ | ||
695 | |||
696 | /** | ||
697 | * struct drm_vmw_present_arg | ||
698 | * @fb_id: framebuffer id to present / read back from. | ||
699 | * @sid: Surface id to present from. | ||
700 | * @dest_x: X placement coordinate for surface. | ||
701 | * @dest_y: Y placement coordinate for surface. | ||
702 | * @clips_ptr: Pointer to an array of clip rects cast to an uint64_t. | ||
703 | * @num_clips: Number of cliprects given relative to the framebuffer origin, | ||
704 | * in the same coordinate space as the frame buffer. | ||
705 | * @pad64: Unused 64-bit padding. | ||
706 | * | ||
707 | * Input argument to the DRM_VMW_PRESENT ioctl. | ||
708 | */ | ||
709 | |||
710 | struct drm_vmw_present_arg { | ||
711 | uint32_t fb_id; | ||
712 | uint32_t sid; | ||
713 | int32_t dest_x; | ||
714 | int32_t dest_y; | ||
715 | uint64_t clips_ptr; | ||
716 | uint32_t num_clips; | ||
717 | uint32_t pad64; | ||
718 | }; | ||
719 | |||
720 | |||
721 | /*************************************************************************/ | ||
722 | /** | ||
723 | * DRM_VMW_PRESENT_READBACK | ||
724 | * | ||
725 | * Executes an SVGA present readback from a given fb to the dma buffer | ||
726 | * currently bound as the fb. If there is no dma buffer bound to the fb, | ||
727 | * an error will be returned. | ||
728 | * | ||
729 | */ | ||
730 | |||
731 | /** | ||
732 | * struct drm_vmw_present_arg | ||
733 | * @fb_id: fb_id to present / read back from. | ||
734 | * @num_clips: Number of cliprects. | ||
735 | * @clips_ptr: Pointer to an array of clip rects cast to an uint64_t. | ||
736 | * @fence_rep: Pointer to a struct drm_vmw_fence_rep, cast to an uint64_t. | ||
737 | * If this member is NULL, then the ioctl should not return a fence. | ||
738 | */ | ||
739 | |||
740 | struct drm_vmw_present_readback_arg { | ||
741 | uint32_t fb_id; | ||
742 | uint32_t num_clips; | ||
743 | uint64_t clips_ptr; | ||
744 | uint64_t fence_rep; | ||
745 | }; | ||
746 | |||
684 | 747 | ||
685 | #endif | 748 | #endif |