Merge tag 'core_guards_for_6.5_rc1' of git://git.kernel.org/pub/scm/linux/kernel...
[platform/kernel/linux-rpi.git] / drivers / gpu / drm / vmwgfx / vmwgfx_surface.c
1 // SPDX-License-Identifier: GPL-2.0 OR MIT
2 /**************************************************************************
3  *
4  * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24  * USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27
28 #include "vmwgfx_bo.h"
29 #include "vmwgfx_drv.h"
30 #include "vmwgfx_resource_priv.h"
31 #include "vmwgfx_so.h"
32 #include "vmwgfx_binding.h"
33 #include "vmw_surface_cache.h"
34 #include "device_include/svga3d_surfacedefs.h"
35
36 #include <drm/ttm/ttm_placement.h>
37
38 #define SVGA3D_FLAGS_64(upper32, lower32) (((uint64_t)upper32 << 32) | lower32)
39 #define SVGA3D_FLAGS_UPPER_32(svga3d_flags) (svga3d_flags >> 32)
40 #define SVGA3D_FLAGS_LOWER_32(svga3d_flags) \
41         (svga3d_flags & ((uint64_t)U32_MAX))
42
43 /**
44  * struct vmw_user_surface - User-space visible surface resource
45  *
46  * @prime:          The TTM prime object.
47  * @base:           The TTM base object handling user-space visibility.
48  * @srf:            The surface metadata.
49  * @master:         Master of the creating client. Used for security check.
50  */
51 struct vmw_user_surface {
52         struct ttm_prime_object prime;
53         struct vmw_surface srf;
54         struct drm_master *master;
55 };
56
57 /**
58  * struct vmw_surface_offset - Backing store mip level offset info
59  *
60  * @face:           Surface face.
61  * @mip:            Mip level.
62  * @bo_offset:      Offset into backing store of this mip level.
63  *
64  */
65 struct vmw_surface_offset {
66         uint32_t face;
67         uint32_t mip;
68         uint32_t bo_offset;
69 };
70
71 /**
72  * struct vmw_surface_dirty - Surface dirty-tracker
73  * @cache: Cached layout information of the surface.
74  * @num_subres: Number of subresources.
75  * @boxes: Array of SVGA3dBoxes indicating dirty regions. One per subresource.
76  */
77 struct vmw_surface_dirty {
78         struct vmw_surface_cache cache;
79         u32 num_subres;
80         SVGA3dBox boxes[];
81 };
82
83 static void vmw_user_surface_free(struct vmw_resource *res);
84 static struct vmw_resource *
85 vmw_user_surface_base_to_res(struct ttm_base_object *base);
86 static int vmw_legacy_srf_bind(struct vmw_resource *res,
87                                struct ttm_validate_buffer *val_buf);
88 static int vmw_legacy_srf_unbind(struct vmw_resource *res,
89                                  bool readback,
90                                  struct ttm_validate_buffer *val_buf);
91 static int vmw_legacy_srf_create(struct vmw_resource *res);
92 static int vmw_legacy_srf_destroy(struct vmw_resource *res);
93 static int vmw_gb_surface_create(struct vmw_resource *res);
94 static int vmw_gb_surface_bind(struct vmw_resource *res,
95                                struct ttm_validate_buffer *val_buf);
96 static int vmw_gb_surface_unbind(struct vmw_resource *res,
97                                  bool readback,
98                                  struct ttm_validate_buffer *val_buf);
99 static int vmw_gb_surface_destroy(struct vmw_resource *res);
100 static int
101 vmw_gb_surface_define_internal(struct drm_device *dev,
102                                struct drm_vmw_gb_surface_create_ext_req *req,
103                                struct drm_vmw_gb_surface_create_rep *rep,
104                                struct drm_file *file_priv);
105 static int
106 vmw_gb_surface_reference_internal(struct drm_device *dev,
107                                   struct drm_vmw_surface_arg *req,
108                                   struct drm_vmw_gb_surface_ref_ext_rep *rep,
109                                   struct drm_file *file_priv);
110
111 static void vmw_surface_dirty_free(struct vmw_resource *res);
112 static int vmw_surface_dirty_alloc(struct vmw_resource *res);
113 static int vmw_surface_dirty_sync(struct vmw_resource *res);
114 static void vmw_surface_dirty_range_add(struct vmw_resource *res, size_t start,
115                                         size_t end);
116 static int vmw_surface_clean(struct vmw_resource *res);
117
118 static const struct vmw_user_resource_conv user_surface_conv = {
119         .object_type = VMW_RES_SURFACE,
120         .base_obj_to_res = vmw_user_surface_base_to_res,
121         .res_free = vmw_user_surface_free
122 };
123
124 const struct vmw_user_resource_conv *user_surface_converter =
125         &user_surface_conv;
126
127 static const struct vmw_res_func vmw_legacy_surface_func = {
128         .res_type = vmw_res_surface,
129         .needs_guest_memory = false,
130         .may_evict = true,
131         .prio = 1,
132         .dirty_prio = 1,
133         .type_name = "legacy surfaces",
134         .domain = VMW_BO_DOMAIN_GMR,
135         .busy_domain = VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM,
136         .create = &vmw_legacy_srf_create,
137         .destroy = &vmw_legacy_srf_destroy,
138         .bind = &vmw_legacy_srf_bind,
139         .unbind = &vmw_legacy_srf_unbind
140 };
141
142 static const struct vmw_res_func vmw_gb_surface_func = {
143         .res_type = vmw_res_surface,
144         .needs_guest_memory = true,
145         .may_evict = true,
146         .prio = 1,
147         .dirty_prio = 2,
148         .type_name = "guest backed surfaces",
149         .domain = VMW_BO_DOMAIN_MOB,
150         .busy_domain = VMW_BO_DOMAIN_MOB,
151         .create = vmw_gb_surface_create,
152         .destroy = vmw_gb_surface_destroy,
153         .bind = vmw_gb_surface_bind,
154         .unbind = vmw_gb_surface_unbind,
155         .dirty_alloc = vmw_surface_dirty_alloc,
156         .dirty_free = vmw_surface_dirty_free,
157         .dirty_sync = vmw_surface_dirty_sync,
158         .dirty_range_add = vmw_surface_dirty_range_add,
159         .clean = vmw_surface_clean,
160 };
161
162 /*
163  * struct vmw_surface_dma - SVGA3D DMA command
164  */
165 struct vmw_surface_dma {
166         SVGA3dCmdHeader header;
167         SVGA3dCmdSurfaceDMA body;
168         SVGA3dCopyBox cb;
169         SVGA3dCmdSurfaceDMASuffix suffix;
170 };
171
172 /*
173  * struct vmw_surface_define - SVGA3D Surface Define command
174  */
175 struct vmw_surface_define {
176         SVGA3dCmdHeader header;
177         SVGA3dCmdDefineSurface body;
178 };
179
180 /*
181  * struct vmw_surface_destroy - SVGA3D Surface Destroy command
182  */
183 struct vmw_surface_destroy {
184         SVGA3dCmdHeader header;
185         SVGA3dCmdDestroySurface body;
186 };
187
188
189 /**
190  * vmw_surface_dma_size - Compute fifo size for a dma command.
191  *
192  * @srf: Pointer to a struct vmw_surface
193  *
194  * Computes the required size for a surface dma command for backup or
195  * restoration of the surface represented by @srf.
196  */
197 static inline uint32_t vmw_surface_dma_size(const struct vmw_surface *srf)
198 {
199         return srf->metadata.num_sizes * sizeof(struct vmw_surface_dma);
200 }
201
202
203 /**
204  * vmw_surface_define_size - Compute fifo size for a surface define command.
205  *
206  * @srf: Pointer to a struct vmw_surface
207  *
208  * Computes the required size for a surface define command for the definition
209  * of the surface represented by @srf.
210  */
211 static inline uint32_t vmw_surface_define_size(const struct vmw_surface *srf)
212 {
213         return sizeof(struct vmw_surface_define) + srf->metadata.num_sizes *
214                 sizeof(SVGA3dSize);
215 }
216
217
218 /**
219  * vmw_surface_destroy_size - Compute fifo size for a surface destroy command.
220  *
221  * Computes the required size for a surface destroy command for the destruction
222  * of a hw surface.
223  */
224 static inline uint32_t vmw_surface_destroy_size(void)
225 {
226         return sizeof(struct vmw_surface_destroy);
227 }
228
229 /**
230  * vmw_surface_destroy_encode - Encode a surface_destroy command.
231  *
232  * @id: The surface id
233  * @cmd_space: Pointer to memory area in which the commands should be encoded.
234  */
235 static void vmw_surface_destroy_encode(uint32_t id,
236                                        void *cmd_space)
237 {
238         struct vmw_surface_destroy *cmd = (struct vmw_surface_destroy *)
239                 cmd_space;
240
241         cmd->header.id = SVGA_3D_CMD_SURFACE_DESTROY;
242         cmd->header.size = sizeof(cmd->body);
243         cmd->body.sid = id;
244 }
245
246 /**
247  * vmw_surface_define_encode - Encode a surface_define command.
248  *
249  * @srf: Pointer to a struct vmw_surface object.
250  * @cmd_space: Pointer to memory area in which the commands should be encoded.
251  */
252 static void vmw_surface_define_encode(const struct vmw_surface *srf,
253                                       void *cmd_space)
254 {
255         struct vmw_surface_define *cmd = (struct vmw_surface_define *)
256                 cmd_space;
257         struct drm_vmw_size *src_size;
258         SVGA3dSize *cmd_size;
259         uint32_t cmd_len;
260         int i;
261
262         cmd_len = sizeof(cmd->body) + srf->metadata.num_sizes *
263                 sizeof(SVGA3dSize);
264
265         cmd->header.id = SVGA_3D_CMD_SURFACE_DEFINE;
266         cmd->header.size = cmd_len;
267         cmd->body.sid = srf->res.id;
268         /*
269          * Downcast of surfaceFlags, was upcasted when received from user-space,
270          * since driver internally stores as 64 bit.
271          * For legacy surface define only 32 bit flag is supported.
272          */
273         cmd->body.surfaceFlags = (SVGA3dSurface1Flags)srf->metadata.flags;
274         cmd->body.format = srf->metadata.format;
275         for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i)
276                 cmd->body.face[i].numMipLevels = srf->metadata.mip_levels[i];
277
278         cmd += 1;
279         cmd_size = (SVGA3dSize *) cmd;
280         src_size = srf->metadata.sizes;
281
282         for (i = 0; i < srf->metadata.num_sizes; ++i, cmd_size++, src_size++) {
283                 cmd_size->width = src_size->width;
284                 cmd_size->height = src_size->height;
285                 cmd_size->depth = src_size->depth;
286         }
287 }
288
289 /**
290  * vmw_surface_dma_encode - Encode a surface_dma command.
291  *
292  * @srf: Pointer to a struct vmw_surface object.
293  * @cmd_space: Pointer to memory area in which the commands should be encoded.
294  * @ptr: Pointer to an SVGAGuestPtr indicating where the surface contents
295  * should be placed or read from.
296  * @to_surface: Boolean whether to DMA to the surface or from the surface.
297  */
298 static void vmw_surface_dma_encode(struct vmw_surface *srf,
299                                    void *cmd_space,
300                                    const SVGAGuestPtr *ptr,
301                                    bool to_surface)
302 {
303         uint32_t i;
304         struct vmw_surface_dma *cmd = (struct vmw_surface_dma *)cmd_space;
305         const struct SVGA3dSurfaceDesc *desc =
306                 vmw_surface_get_desc(srf->metadata.format);
307
308         for (i = 0; i < srf->metadata.num_sizes; ++i) {
309                 SVGA3dCmdHeader *header = &cmd->header;
310                 SVGA3dCmdSurfaceDMA *body = &cmd->body;
311                 SVGA3dCopyBox *cb = &cmd->cb;
312                 SVGA3dCmdSurfaceDMASuffix *suffix = &cmd->suffix;
313                 const struct vmw_surface_offset *cur_offset = &srf->offsets[i];
314                 const struct drm_vmw_size *cur_size = &srf->metadata.sizes[i];
315
316                 header->id = SVGA_3D_CMD_SURFACE_DMA;
317                 header->size = sizeof(*body) + sizeof(*cb) + sizeof(*suffix);
318
319                 body->guest.ptr = *ptr;
320                 body->guest.ptr.offset += cur_offset->bo_offset;
321                 body->guest.pitch = vmw_surface_calculate_pitch(desc, cur_size);
322                 body->host.sid = srf->res.id;
323                 body->host.face = cur_offset->face;
324                 body->host.mipmap = cur_offset->mip;
325                 body->transfer = ((to_surface) ?  SVGA3D_WRITE_HOST_VRAM :
326                                   SVGA3D_READ_HOST_VRAM);
327                 cb->x = 0;
328                 cb->y = 0;
329                 cb->z = 0;
330                 cb->srcx = 0;
331                 cb->srcy = 0;
332                 cb->srcz = 0;
333                 cb->w = cur_size->width;
334                 cb->h = cur_size->height;
335                 cb->d = cur_size->depth;
336
337                 suffix->suffixSize = sizeof(*suffix);
338                 suffix->maximumOffset =
339                         vmw_surface_get_image_buffer_size(desc, cur_size,
340                                                             body->guest.pitch);
341                 suffix->flags.discard = 0;
342                 suffix->flags.unsynchronized = 0;
343                 suffix->flags.reserved = 0;
344                 ++cmd;
345         }
346 };
347
348
349 /**
350  * vmw_hw_surface_destroy - destroy a Device surface
351  *
352  * @res:        Pointer to a struct vmw_resource embedded in a struct
353  *              vmw_surface.
354  *
355  * Destroys a the device surface associated with a struct vmw_surface if
356  * any, and adjusts resource count accordingly.
357  */
358 static void vmw_hw_surface_destroy(struct vmw_resource *res)
359 {
360
361         struct vmw_private *dev_priv = res->dev_priv;
362         void *cmd;
363
364         if (res->func->destroy == vmw_gb_surface_destroy) {
365                 (void) vmw_gb_surface_destroy(res);
366                 return;
367         }
368
369         if (res->id != -1) {
370
371                 cmd = VMW_CMD_RESERVE(dev_priv, vmw_surface_destroy_size());
372                 if (unlikely(!cmd))
373                         return;
374
375                 vmw_surface_destroy_encode(res->id, cmd);
376                 vmw_cmd_commit(dev_priv, vmw_surface_destroy_size());
377
378                 /*
379                  * used_memory_size_atomic, or separate lock
380                  * to avoid taking dev_priv::cmdbuf_mutex in
381                  * the destroy path.
382                  */
383
384                 mutex_lock(&dev_priv->cmdbuf_mutex);
385                 dev_priv->used_memory_size -= res->guest_memory_size;
386                 mutex_unlock(&dev_priv->cmdbuf_mutex);
387         }
388 }
389
390 /**
391  * vmw_legacy_srf_create - Create a device surface as part of the
392  * resource validation process.
393  *
394  * @res: Pointer to a struct vmw_surface.
395  *
396  * If the surface doesn't have a hw id.
397  *
398  * Returns -EBUSY if there wasn't sufficient device resources to
399  * complete the validation. Retry after freeing up resources.
400  *
401  * May return other errors if the kernel is out of guest resources.
402  */
403 static int vmw_legacy_srf_create(struct vmw_resource *res)
404 {
405         struct vmw_private *dev_priv = res->dev_priv;
406         struct vmw_surface *srf;
407         uint32_t submit_size;
408         uint8_t *cmd;
409         int ret;
410
411         if (likely(res->id != -1))
412                 return 0;
413
414         srf = vmw_res_to_srf(res);
415         if (unlikely(dev_priv->used_memory_size + res->guest_memory_size >=
416                      dev_priv->memory_size))
417                 return -EBUSY;
418
419         /*
420          * Alloc id for the resource.
421          */
422
423         ret = vmw_resource_alloc_id(res);
424         if (unlikely(ret != 0)) {
425                 DRM_ERROR("Failed to allocate a surface id.\n");
426                 goto out_no_id;
427         }
428
429         if (unlikely(res->id >= SVGA3D_HB_MAX_SURFACE_IDS)) {
430                 ret = -EBUSY;
431                 goto out_no_fifo;
432         }
433
434         /*
435          * Encode surface define- commands.
436          */
437
438         submit_size = vmw_surface_define_size(srf);
439         cmd = VMW_CMD_RESERVE(dev_priv, submit_size);
440         if (unlikely(!cmd)) {
441                 ret = -ENOMEM;
442                 goto out_no_fifo;
443         }
444
445         vmw_surface_define_encode(srf, cmd);
446         vmw_cmd_commit(dev_priv, submit_size);
447         vmw_fifo_resource_inc(dev_priv);
448
449         /*
450          * Surface memory usage accounting.
451          */
452
453         dev_priv->used_memory_size += res->guest_memory_size;
454         return 0;
455
456 out_no_fifo:
457         vmw_resource_release_id(res);
458 out_no_id:
459         return ret;
460 }
461
462 /**
463  * vmw_legacy_srf_dma - Copy backup data to or from a legacy surface.
464  *
465  * @res:            Pointer to a struct vmw_res embedded in a struct
466  *                  vmw_surface.
467  * @val_buf:        Pointer to a struct ttm_validate_buffer containing
468  *                  information about the backup buffer.
469  * @bind:           Boolean wether to DMA to the surface.
470  *
471  * Transfer backup data to or from a legacy surface as part of the
472  * validation process.
473  * May return other errors if the kernel is out of guest resources.
474  * The backup buffer will be fenced or idle upon successful completion,
475  * and if the surface needs persistent backup storage, the backup buffer
476  * will also be returned reserved iff @bind is true.
477  */
478 static int vmw_legacy_srf_dma(struct vmw_resource *res,
479                               struct ttm_validate_buffer *val_buf,
480                               bool bind)
481 {
482         SVGAGuestPtr ptr;
483         struct vmw_fence_obj *fence;
484         uint32_t submit_size;
485         struct vmw_surface *srf = vmw_res_to_srf(res);
486         uint8_t *cmd;
487         struct vmw_private *dev_priv = res->dev_priv;
488
489         BUG_ON(!val_buf->bo);
490         submit_size = vmw_surface_dma_size(srf);
491         cmd = VMW_CMD_RESERVE(dev_priv, submit_size);
492         if (unlikely(!cmd))
493                 return -ENOMEM;
494
495         vmw_bo_get_guest_ptr(val_buf->bo, &ptr);
496         vmw_surface_dma_encode(srf, cmd, &ptr, bind);
497
498         vmw_cmd_commit(dev_priv, submit_size);
499
500         /*
501          * Create a fence object and fence the backup buffer.
502          */
503
504         (void) vmw_execbuf_fence_commands(NULL, dev_priv,
505                                           &fence, NULL);
506
507         vmw_bo_fence_single(val_buf->bo, fence);
508
509         if (likely(fence != NULL))
510                 vmw_fence_obj_unreference(&fence);
511
512         return 0;
513 }
514
515 /**
516  * vmw_legacy_srf_bind - Perform a legacy surface bind as part of the
517  *                       surface validation process.
518  *
519  * @res:            Pointer to a struct vmw_res embedded in a struct
520  *                  vmw_surface.
521  * @val_buf:        Pointer to a struct ttm_validate_buffer containing
522  *                  information about the backup buffer.
523  *
524  * This function will copy backup data to the surface if the
525  * backup buffer is dirty.
526  */
527 static int vmw_legacy_srf_bind(struct vmw_resource *res,
528                                struct ttm_validate_buffer *val_buf)
529 {
530         if (!res->guest_memory_dirty)
531                 return 0;
532
533         return vmw_legacy_srf_dma(res, val_buf, true);
534 }
535
536
537 /**
538  * vmw_legacy_srf_unbind - Perform a legacy surface unbind as part of the
539  *                         surface eviction process.
540  *
541  * @res:            Pointer to a struct vmw_res embedded in a struct
542  *                  vmw_surface.
543  * @readback:       Readback - only true if dirty
544  * @val_buf:        Pointer to a struct ttm_validate_buffer containing
545  *                  information about the backup buffer.
546  *
547  * This function will copy backup data from the surface.
548  */
549 static int vmw_legacy_srf_unbind(struct vmw_resource *res,
550                                  bool readback,
551                                  struct ttm_validate_buffer *val_buf)
552 {
553         if (unlikely(readback))
554                 return vmw_legacy_srf_dma(res, val_buf, false);
555         return 0;
556 }
557
558 /**
559  * vmw_legacy_srf_destroy - Destroy a device surface as part of a
560  *                          resource eviction process.
561  *
562  * @res:            Pointer to a struct vmw_res embedded in a struct
563  *                  vmw_surface.
564  */
565 static int vmw_legacy_srf_destroy(struct vmw_resource *res)
566 {
567         struct vmw_private *dev_priv = res->dev_priv;
568         uint32_t submit_size;
569         uint8_t *cmd;
570
571         BUG_ON(res->id == -1);
572
573         /*
574          * Encode the dma- and surface destroy commands.
575          */
576
577         submit_size = vmw_surface_destroy_size();
578         cmd = VMW_CMD_RESERVE(dev_priv, submit_size);
579         if (unlikely(!cmd))
580                 return -ENOMEM;
581
582         vmw_surface_destroy_encode(res->id, cmd);
583         vmw_cmd_commit(dev_priv, submit_size);
584
585         /*
586          * Surface memory usage accounting.
587          */
588
589         dev_priv->used_memory_size -= res->guest_memory_size;
590
591         /*
592          * Release the surface ID.
593          */
594
595         vmw_resource_release_id(res);
596         vmw_fifo_resource_dec(dev_priv);
597
598         return 0;
599 }
600
601
602 /**
603  * vmw_surface_init - initialize a struct vmw_surface
604  *
605  * @dev_priv:       Pointer to a device private struct.
606  * @srf:            Pointer to the struct vmw_surface to initialize.
607  * @res_free:       Pointer to a resource destructor used to free
608  *                  the object.
609  */
610 static int vmw_surface_init(struct vmw_private *dev_priv,
611                             struct vmw_surface *srf,
612                             void (*res_free) (struct vmw_resource *res))
613 {
614         int ret;
615         struct vmw_resource *res = &srf->res;
616
617         BUG_ON(!res_free);
618         ret = vmw_resource_init(dev_priv, res, true, res_free,
619                                 (dev_priv->has_mob) ? &vmw_gb_surface_func :
620                                 &vmw_legacy_surface_func);
621
622         if (unlikely(ret != 0)) {
623                 res_free(res);
624                 return ret;
625         }
626
627         /*
628          * The surface won't be visible to hardware until a
629          * surface validate.
630          */
631
632         INIT_LIST_HEAD(&srf->view_list);
633         res->hw_destroy = vmw_hw_surface_destroy;
634         return ret;
635 }
636
637 /**
638  * vmw_user_surface_base_to_res - TTM base object to resource converter for
639  *                                user visible surfaces
640  *
641  * @base:           Pointer to a TTM base object
642  *
643  * Returns the struct vmw_resource embedded in a struct vmw_surface
644  * for the user-visible object identified by the TTM base object @base.
645  */
646 static struct vmw_resource *
647 vmw_user_surface_base_to_res(struct ttm_base_object *base)
648 {
649         return &(container_of(base, struct vmw_user_surface,
650                               prime.base)->srf.res);
651 }
652
653 /**
654  * vmw_user_surface_free - User visible surface resource destructor
655  *
656  * @res:            A struct vmw_resource embedded in a struct vmw_surface.
657  */
658 static void vmw_user_surface_free(struct vmw_resource *res)
659 {
660         struct vmw_surface *srf = vmw_res_to_srf(res);
661         struct vmw_user_surface *user_srf =
662             container_of(srf, struct vmw_user_surface, srf);
663
664         WARN_ON_ONCE(res->dirty);
665         if (user_srf->master)
666                 drm_master_put(&user_srf->master);
667         kfree(srf->offsets);
668         kfree(srf->metadata.sizes);
669         kfree(srf->snooper.image);
670         ttm_prime_object_kfree(user_srf, prime);
671 }
672
673 /**
674  * vmw_user_surface_base_release - User visible surface TTM base object destructor
675  *
676  * @p_base:         Pointer to a pointer to a TTM base object
677  *                  embedded in a struct vmw_user_surface.
678  *
679  * Drops the base object's reference on its resource, and the
680  * pointer pointed to by *p_base is set to NULL.
681  */
682 static void vmw_user_surface_base_release(struct ttm_base_object **p_base)
683 {
684         struct ttm_base_object *base = *p_base;
685         struct vmw_user_surface *user_srf =
686             container_of(base, struct vmw_user_surface, prime.base);
687         struct vmw_resource *res = &user_srf->srf.res;
688
689         if (res->guest_memory_bo)
690                 drm_gem_object_put(&res->guest_memory_bo->tbo.base);
691
692         *p_base = NULL;
693         vmw_resource_unreference(&res);
694 }
695
696 /**
697  * vmw_surface_destroy_ioctl - Ioctl function implementing
698  *                                  the user surface destroy functionality.
699  *
700  * @dev:            Pointer to a struct drm_device.
701  * @data:           Pointer to data copied from / to user-space.
702  * @file_priv:      Pointer to a drm file private structure.
703  */
704 int vmw_surface_destroy_ioctl(struct drm_device *dev, void *data,
705                               struct drm_file *file_priv)
706 {
707         struct drm_vmw_surface_arg *arg = (struct drm_vmw_surface_arg *)data;
708         struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
709
710         return ttm_ref_object_base_unref(tfile, arg->sid);
711 }
712
713 /**
714  * vmw_surface_define_ioctl - Ioctl function implementing
715  *                                  the user surface define functionality.
716  *
717  * @dev:            Pointer to a struct drm_device.
718  * @data:           Pointer to data copied from / to user-space.
719  * @file_priv:      Pointer to a drm file private structure.
720  */
721 int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
722                              struct drm_file *file_priv)
723 {
724         struct vmw_private *dev_priv = vmw_priv(dev);
725         struct vmw_user_surface *user_srf;
726         struct vmw_surface *srf;
727         struct vmw_surface_metadata *metadata;
728         struct vmw_resource *res;
729         struct vmw_resource *tmp;
730         union drm_vmw_surface_create_arg *arg =
731             (union drm_vmw_surface_create_arg *)data;
732         struct drm_vmw_surface_create_req *req = &arg->req;
733         struct drm_vmw_surface_arg *rep = &arg->rep;
734         struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
735         int ret;
736         int i, j;
737         uint32_t cur_bo_offset;
738         struct drm_vmw_size *cur_size;
739         struct vmw_surface_offset *cur_offset;
740         uint32_t num_sizes;
741         const SVGA3dSurfaceDesc *desc;
742
743         num_sizes = 0;
744         for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) {
745                 if (req->mip_levels[i] > DRM_VMW_MAX_MIP_LEVELS)
746                         return -EINVAL;
747                 num_sizes += req->mip_levels[i];
748         }
749
750         if (num_sizes > DRM_VMW_MAX_SURFACE_FACES * DRM_VMW_MAX_MIP_LEVELS ||
751             num_sizes == 0)
752                 return -EINVAL;
753
754         desc = vmw_surface_get_desc(req->format);
755         if (unlikely(desc->blockDesc == SVGA3DBLOCKDESC_NONE)) {
756                 VMW_DEBUG_USER("Invalid format %d for surface creation.\n",
757                                req->format);
758                 return -EINVAL;
759         }
760
761         user_srf = kzalloc(sizeof(*user_srf), GFP_KERNEL);
762         if (unlikely(!user_srf)) {
763                 ret = -ENOMEM;
764                 goto out_unlock;
765         }
766
767         srf = &user_srf->srf;
768         metadata = &srf->metadata;
769         res = &srf->res;
770
771         /* Driver internally stores as 64-bit flags */
772         metadata->flags = (SVGA3dSurfaceAllFlags)req->flags;
773         metadata->format = req->format;
774         metadata->scanout = req->scanout;
775
776         memcpy(metadata->mip_levels, req->mip_levels,
777                sizeof(metadata->mip_levels));
778         metadata->num_sizes = num_sizes;
779         metadata->sizes =
780                 memdup_user((struct drm_vmw_size __user *)(unsigned long)
781                             req->size_addr,
782                             sizeof(*metadata->sizes) * metadata->num_sizes);
783         if (IS_ERR(metadata->sizes)) {
784                 ret = PTR_ERR(metadata->sizes);
785                 goto out_no_sizes;
786         }
787         srf->offsets = kmalloc_array(metadata->num_sizes, sizeof(*srf->offsets),
788                                      GFP_KERNEL);
789         if (unlikely(!srf->offsets)) {
790                 ret = -ENOMEM;
791                 goto out_no_offsets;
792         }
793
794         metadata->base_size = *srf->metadata.sizes;
795         metadata->autogen_filter = SVGA3D_TEX_FILTER_NONE;
796         metadata->multisample_count = 0;
797         metadata->multisample_pattern = SVGA3D_MS_PATTERN_NONE;
798         metadata->quality_level = SVGA3D_MS_QUALITY_NONE;
799
800         cur_bo_offset = 0;
801         cur_offset = srf->offsets;
802         cur_size = metadata->sizes;
803
804         for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) {
805                 for (j = 0; j < metadata->mip_levels[i]; ++j) {
806                         uint32_t stride = vmw_surface_calculate_pitch(
807                                                   desc, cur_size);
808
809                         cur_offset->face = i;
810                         cur_offset->mip = j;
811                         cur_offset->bo_offset = cur_bo_offset;
812                         cur_bo_offset += vmw_surface_get_image_buffer_size
813                                 (desc, cur_size, stride);
814                         ++cur_offset;
815                         ++cur_size;
816                 }
817         }
818         res->guest_memory_size = cur_bo_offset;
819         if (metadata->scanout &&
820             metadata->num_sizes == 1 &&
821             metadata->sizes[0].width == VMW_CURSOR_SNOOP_WIDTH &&
822             metadata->sizes[0].height == VMW_CURSOR_SNOOP_HEIGHT &&
823             metadata->format == VMW_CURSOR_SNOOP_FORMAT) {
824                 const struct SVGA3dSurfaceDesc *desc =
825                         vmw_surface_get_desc(VMW_CURSOR_SNOOP_FORMAT);
826                 const u32 cursor_size_bytes = VMW_CURSOR_SNOOP_WIDTH *
827                                               VMW_CURSOR_SNOOP_HEIGHT *
828                                               desc->pitchBytesPerBlock;
829                 srf->snooper.image = kzalloc(cursor_size_bytes, GFP_KERNEL);
830                 if (!srf->snooper.image) {
831                         DRM_ERROR("Failed to allocate cursor_image\n");
832                         ret = -ENOMEM;
833                         goto out_no_copy;
834                 }
835         } else {
836                 srf->snooper.image = NULL;
837         }
838
839         user_srf->prime.base.shareable = false;
840         user_srf->prime.base.tfile = NULL;
841         if (drm_is_primary_client(file_priv))
842                 user_srf->master = drm_file_get_master(file_priv);
843
844         /**
845          * From this point, the generic resource management functions
846          * destroy the object on failure.
847          */
848
849         ret = vmw_surface_init(dev_priv, srf, vmw_user_surface_free);
850         if (unlikely(ret != 0))
851                 goto out_unlock;
852
853         /*
854          * A gb-aware client referencing a shared surface will
855          * expect a backup buffer to be present.
856          */
857         if (dev_priv->has_mob && req->shareable) {
858                 uint32_t backup_handle;
859
860                 ret = vmw_gem_object_create_with_handle(dev_priv,
861                                                         file_priv,
862                                                         res->guest_memory_size,
863                                                         &backup_handle,
864                                                         &res->guest_memory_bo);
865                 if (unlikely(ret != 0)) {
866                         vmw_resource_unreference(&res);
867                         goto out_unlock;
868                 }
869                 vmw_bo_reference(res->guest_memory_bo);
870                 /*
871                  * We don't expose the handle to the userspace and surface
872                  * already holds a gem reference
873                  */
874                 drm_gem_handle_delete(file_priv, backup_handle);
875         }
876
877         tmp = vmw_resource_reference(&srf->res);
878         ret = ttm_prime_object_init(tfile, res->guest_memory_size, &user_srf->prime,
879                                     req->shareable, VMW_RES_SURFACE,
880                                     &vmw_user_surface_base_release);
881
882         if (unlikely(ret != 0)) {
883                 vmw_resource_unreference(&tmp);
884                 vmw_resource_unreference(&res);
885                 goto out_unlock;
886         }
887
888         rep->sid = user_srf->prime.base.handle;
889         vmw_resource_unreference(&res);
890
891         return 0;
892 out_no_copy:
893         kfree(srf->offsets);
894 out_no_offsets:
895         kfree(metadata->sizes);
896 out_no_sizes:
897         ttm_prime_object_kfree(user_srf, prime);
898 out_unlock:
899         return ret;
900 }
901
902
903 static int
904 vmw_surface_handle_reference(struct vmw_private *dev_priv,
905                              struct drm_file *file_priv,
906                              uint32_t u_handle,
907                              enum drm_vmw_handle_type handle_type,
908                              struct ttm_base_object **base_p)
909 {
910         struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
911         struct vmw_user_surface *user_srf;
912         uint32_t handle;
913         struct ttm_base_object *base;
914         int ret;
915
916         if (handle_type == DRM_VMW_HANDLE_PRIME) {
917                 ret = ttm_prime_fd_to_handle(tfile, u_handle, &handle);
918                 if (unlikely(ret != 0))
919                         return ret;
920         } else {
921                 handle = u_handle;
922         }
923
924         ret = -EINVAL;
925         base = ttm_base_object_lookup_for_ref(dev_priv->tdev, handle);
926         if (unlikely(!base)) {
927                 VMW_DEBUG_USER("Could not find surface to reference.\n");
928                 goto out_no_lookup;
929         }
930
931         if (unlikely(ttm_base_object_type(base) != VMW_RES_SURFACE)) {
932                 VMW_DEBUG_USER("Referenced object is not a surface.\n");
933                 goto out_bad_resource;
934         }
935         if (handle_type != DRM_VMW_HANDLE_PRIME) {
936                 bool require_exist = false;
937
938                 user_srf = container_of(base, struct vmw_user_surface,
939                                         prime.base);
940
941                 /* Error out if we are unauthenticated primary */
942                 if (drm_is_primary_client(file_priv) &&
943                     !file_priv->authenticated) {
944                         ret = -EACCES;
945                         goto out_bad_resource;
946                 }
947
948                 /*
949                  * Make sure the surface creator has the same
950                  * authenticating master, or is already registered with us.
951                  */
952                 if (drm_is_primary_client(file_priv) &&
953                     user_srf->master != file_priv->master)
954                         require_exist = true;
955
956                 if (unlikely(drm_is_render_client(file_priv)))
957                         require_exist = true;
958
959                 ret = ttm_ref_object_add(tfile, base, NULL, require_exist);
960                 if (unlikely(ret != 0)) {
961                         DRM_ERROR("Could not add a reference to a surface.\n");
962                         goto out_bad_resource;
963                 }
964         }
965
966         *base_p = base;
967         return 0;
968
969 out_bad_resource:
970         ttm_base_object_unref(&base);
971 out_no_lookup:
972         if (handle_type == DRM_VMW_HANDLE_PRIME)
973                 (void) ttm_ref_object_base_unref(tfile, handle);
974
975         return ret;
976 }
977
978 /**
979  * vmw_surface_reference_ioctl - Ioctl function implementing
980  *                                  the user surface reference functionality.
981  *
982  * @dev:            Pointer to a struct drm_device.
983  * @data:           Pointer to data copied from / to user-space.
984  * @file_priv:      Pointer to a drm file private structure.
985  */
986 int vmw_surface_reference_ioctl(struct drm_device *dev, void *data,
987                                 struct drm_file *file_priv)
988 {
989         struct vmw_private *dev_priv = vmw_priv(dev);
990         union drm_vmw_surface_reference_arg *arg =
991             (union drm_vmw_surface_reference_arg *)data;
992         struct drm_vmw_surface_arg *req = &arg->req;
993         struct drm_vmw_surface_create_req *rep = &arg->rep;
994         struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
995         struct vmw_surface *srf;
996         struct vmw_user_surface *user_srf;
997         struct drm_vmw_size __user *user_sizes;
998         struct ttm_base_object *base;
999         int ret;
1000
1001         ret = vmw_surface_handle_reference(dev_priv, file_priv, req->sid,
1002                                            req->handle_type, &base);
1003         if (unlikely(ret != 0))
1004                 return ret;
1005
1006         user_srf = container_of(base, struct vmw_user_surface, prime.base);
1007         srf = &user_srf->srf;
1008
1009         /* Downcast of flags when sending back to user space */
1010         rep->flags = (uint32_t)srf->metadata.flags;
1011         rep->format = srf->metadata.format;
1012         memcpy(rep->mip_levels, srf->metadata.mip_levels,
1013                sizeof(srf->metadata.mip_levels));
1014         user_sizes = (struct drm_vmw_size __user *)(unsigned long)
1015             rep->size_addr;
1016
1017         if (user_sizes)
1018                 ret = copy_to_user(user_sizes, &srf->metadata.base_size,
1019                                    sizeof(srf->metadata.base_size));
1020         if (unlikely(ret != 0)) {
1021                 VMW_DEBUG_USER("copy_to_user failed %p %u\n", user_sizes,
1022                                srf->metadata.num_sizes);
1023                 ttm_ref_object_base_unref(tfile, base->handle);
1024                 ret = -EFAULT;
1025         }
1026
1027         ttm_base_object_unref(&base);
1028
1029         return ret;
1030 }
1031
1032 /**
1033  * vmw_gb_surface_create - Encode a surface_define command.
1034  *
1035  * @res:        Pointer to a struct vmw_resource embedded in a struct
1036  *              vmw_surface.
1037  */
1038 static int vmw_gb_surface_create(struct vmw_resource *res)
1039 {
1040         struct vmw_private *dev_priv = res->dev_priv;
1041         struct vmw_surface *srf = vmw_res_to_srf(res);
1042         struct vmw_surface_metadata *metadata = &srf->metadata;
1043         uint32_t cmd_len, cmd_id, submit_len;
1044         int ret;
1045         struct {
1046                 SVGA3dCmdHeader header;
1047                 SVGA3dCmdDefineGBSurface body;
1048         } *cmd;
1049         struct {
1050                 SVGA3dCmdHeader header;
1051                 SVGA3dCmdDefineGBSurface_v2 body;
1052         } *cmd2;
1053         struct {
1054                 SVGA3dCmdHeader header;
1055                 SVGA3dCmdDefineGBSurface_v3 body;
1056         } *cmd3;
1057         struct {
1058                 SVGA3dCmdHeader header;
1059                 SVGA3dCmdDefineGBSurface_v4 body;
1060         } *cmd4;
1061
1062         if (likely(res->id != -1))
1063                 return 0;
1064
1065         vmw_fifo_resource_inc(dev_priv);
1066         ret = vmw_resource_alloc_id(res);
1067         if (unlikely(ret != 0)) {
1068                 DRM_ERROR("Failed to allocate a surface id.\n");
1069                 goto out_no_id;
1070         }
1071
1072         if (unlikely(res->id >= VMWGFX_NUM_GB_SURFACE)) {
1073                 ret = -EBUSY;
1074                 goto out_no_fifo;
1075         }
1076
1077         if (has_sm5_context(dev_priv) && metadata->array_size > 0) {
1078                 cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V4;
1079                 cmd_len = sizeof(cmd4->body);
1080                 submit_len = sizeof(*cmd4);
1081         } else if (has_sm4_1_context(dev_priv) && metadata->array_size > 0) {
1082                 cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V3;
1083                 cmd_len = sizeof(cmd3->body);
1084                 submit_len = sizeof(*cmd3);
1085         } else if (metadata->array_size > 0) {
1086                 /* VMW_SM_4 support verified at creation time. */
1087                 cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V2;
1088                 cmd_len = sizeof(cmd2->body);
1089                 submit_len = sizeof(*cmd2);
1090         } else {
1091                 cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE;
1092                 cmd_len = sizeof(cmd->body);
1093                 submit_len = sizeof(*cmd);
1094         }
1095
1096         cmd = VMW_CMD_RESERVE(dev_priv, submit_len);
1097         cmd2 = (typeof(cmd2))cmd;
1098         cmd3 = (typeof(cmd3))cmd;
1099         cmd4 = (typeof(cmd4))cmd;
1100         if (unlikely(!cmd)) {
1101                 ret = -ENOMEM;
1102                 goto out_no_fifo;
1103         }
1104
1105         if (has_sm5_context(dev_priv) && metadata->array_size > 0) {
1106                 cmd4->header.id = cmd_id;
1107                 cmd4->header.size = cmd_len;
1108                 cmd4->body.sid = srf->res.id;
1109                 cmd4->body.surfaceFlags = metadata->flags;
1110                 cmd4->body.format = metadata->format;
1111                 cmd4->body.numMipLevels = metadata->mip_levels[0];
1112                 cmd4->body.multisampleCount = metadata->multisample_count;
1113                 cmd4->body.multisamplePattern = metadata->multisample_pattern;
1114                 cmd4->body.qualityLevel = metadata->quality_level;
1115                 cmd4->body.autogenFilter = metadata->autogen_filter;
1116                 cmd4->body.size.width = metadata->base_size.width;
1117                 cmd4->body.size.height = metadata->base_size.height;
1118                 cmd4->body.size.depth = metadata->base_size.depth;
1119                 cmd4->body.arraySize = metadata->array_size;
1120                 cmd4->body.bufferByteStride = metadata->buffer_byte_stride;
1121         } else if (has_sm4_1_context(dev_priv) && metadata->array_size > 0) {
1122                 cmd3->header.id = cmd_id;
1123                 cmd3->header.size = cmd_len;
1124                 cmd3->body.sid = srf->res.id;
1125                 cmd3->body.surfaceFlags = metadata->flags;
1126                 cmd3->body.format = metadata->format;
1127                 cmd3->body.numMipLevels = metadata->mip_levels[0];
1128                 cmd3->body.multisampleCount = metadata->multisample_count;
1129                 cmd3->body.multisamplePattern = metadata->multisample_pattern;
1130                 cmd3->body.qualityLevel = metadata->quality_level;
1131                 cmd3->body.autogenFilter = metadata->autogen_filter;
1132                 cmd3->body.size.width = metadata->base_size.width;
1133                 cmd3->body.size.height = metadata->base_size.height;
1134                 cmd3->body.size.depth = metadata->base_size.depth;
1135                 cmd3->body.arraySize = metadata->array_size;
1136         } else if (metadata->array_size > 0) {
1137                 cmd2->header.id = cmd_id;
1138                 cmd2->header.size = cmd_len;
1139                 cmd2->body.sid = srf->res.id;
1140                 cmd2->body.surfaceFlags = metadata->flags;
1141                 cmd2->body.format = metadata->format;
1142                 cmd2->body.numMipLevels = metadata->mip_levels[0];
1143                 cmd2->body.multisampleCount = metadata->multisample_count;
1144                 cmd2->body.autogenFilter = metadata->autogen_filter;
1145                 cmd2->body.size.width = metadata->base_size.width;
1146                 cmd2->body.size.height = metadata->base_size.height;
1147                 cmd2->body.size.depth = metadata->base_size.depth;
1148                 cmd2->body.arraySize = metadata->array_size;
1149         } else {
1150                 cmd->header.id = cmd_id;
1151                 cmd->header.size = cmd_len;
1152                 cmd->body.sid = srf->res.id;
1153                 cmd->body.surfaceFlags = metadata->flags;
1154                 cmd->body.format = metadata->format;
1155                 cmd->body.numMipLevels = metadata->mip_levels[0];
1156                 cmd->body.multisampleCount = metadata->multisample_count;
1157                 cmd->body.autogenFilter = metadata->autogen_filter;
1158                 cmd->body.size.width = metadata->base_size.width;
1159                 cmd->body.size.height = metadata->base_size.height;
1160                 cmd->body.size.depth = metadata->base_size.depth;
1161         }
1162
1163         vmw_cmd_commit(dev_priv, submit_len);
1164
1165         return 0;
1166
1167 out_no_fifo:
1168         vmw_resource_release_id(res);
1169 out_no_id:
1170         vmw_fifo_resource_dec(dev_priv);
1171         return ret;
1172 }
1173
1174
1175 static int vmw_gb_surface_bind(struct vmw_resource *res,
1176                                struct ttm_validate_buffer *val_buf)
1177 {
1178         struct vmw_private *dev_priv = res->dev_priv;
1179         struct {
1180                 SVGA3dCmdHeader header;
1181                 SVGA3dCmdBindGBSurface body;
1182         } *cmd1;
1183         struct {
1184                 SVGA3dCmdHeader header;
1185                 SVGA3dCmdUpdateGBSurface body;
1186         } *cmd2;
1187         uint32_t submit_size;
1188         struct ttm_buffer_object *bo = val_buf->bo;
1189
1190         BUG_ON(bo->resource->mem_type != VMW_PL_MOB);
1191
1192         submit_size = sizeof(*cmd1) + (res->guest_memory_dirty ? sizeof(*cmd2) : 0);
1193
1194         cmd1 = VMW_CMD_RESERVE(dev_priv, submit_size);
1195         if (unlikely(!cmd1))
1196                 return -ENOMEM;
1197
1198         cmd1->header.id = SVGA_3D_CMD_BIND_GB_SURFACE;
1199         cmd1->header.size = sizeof(cmd1->body);
1200         cmd1->body.sid = res->id;
1201         cmd1->body.mobid = bo->resource->start;
1202         if (res->guest_memory_dirty) {
1203                 cmd2 = (void *) &cmd1[1];
1204                 cmd2->header.id = SVGA_3D_CMD_UPDATE_GB_SURFACE;
1205                 cmd2->header.size = sizeof(cmd2->body);
1206                 cmd2->body.sid = res->id;
1207         }
1208         vmw_cmd_commit(dev_priv, submit_size);
1209
1210         if (res->guest_memory_bo->dirty && res->guest_memory_dirty) {
1211                 /* We've just made a full upload. Cear dirty regions. */
1212                 vmw_bo_dirty_clear_res(res);
1213         }
1214
1215         res->guest_memory_dirty = false;
1216
1217         return 0;
1218 }
1219
1220 static int vmw_gb_surface_unbind(struct vmw_resource *res,
1221                                  bool readback,
1222                                  struct ttm_validate_buffer *val_buf)
1223 {
1224         struct vmw_private *dev_priv = res->dev_priv;
1225         struct ttm_buffer_object *bo = val_buf->bo;
1226         struct vmw_fence_obj *fence;
1227
1228         struct {
1229                 SVGA3dCmdHeader header;
1230                 SVGA3dCmdReadbackGBSurface body;
1231         } *cmd1;
1232         struct {
1233                 SVGA3dCmdHeader header;
1234                 SVGA3dCmdInvalidateGBSurface body;
1235         } *cmd2;
1236         struct {
1237                 SVGA3dCmdHeader header;
1238                 SVGA3dCmdBindGBSurface body;
1239         } *cmd3;
1240         uint32_t submit_size;
1241         uint8_t *cmd;
1242
1243
1244         BUG_ON(bo->resource->mem_type != VMW_PL_MOB);
1245
1246         submit_size = sizeof(*cmd3) + (readback ? sizeof(*cmd1) : sizeof(*cmd2));
1247         cmd = VMW_CMD_RESERVE(dev_priv, submit_size);
1248         if (unlikely(!cmd))
1249                 return -ENOMEM;
1250
1251         if (readback) {
1252                 cmd1 = (void *) cmd;
1253                 cmd1->header.id = SVGA_3D_CMD_READBACK_GB_SURFACE;
1254                 cmd1->header.size = sizeof(cmd1->body);
1255                 cmd1->body.sid = res->id;
1256                 cmd3 = (void *) &cmd1[1];
1257         } else {
1258                 cmd2 = (void *) cmd;
1259                 cmd2->header.id = SVGA_3D_CMD_INVALIDATE_GB_SURFACE;
1260                 cmd2->header.size = sizeof(cmd2->body);
1261                 cmd2->body.sid = res->id;
1262                 cmd3 = (void *) &cmd2[1];
1263         }
1264
1265         cmd3->header.id = SVGA_3D_CMD_BIND_GB_SURFACE;
1266         cmd3->header.size = sizeof(cmd3->body);
1267         cmd3->body.sid = res->id;
1268         cmd3->body.mobid = SVGA3D_INVALID_ID;
1269
1270         vmw_cmd_commit(dev_priv, submit_size);
1271
1272         /*
1273          * Create a fence object and fence the backup buffer.
1274          */
1275
1276         (void) vmw_execbuf_fence_commands(NULL, dev_priv,
1277                                           &fence, NULL);
1278
1279         vmw_bo_fence_single(val_buf->bo, fence);
1280
1281         if (likely(fence != NULL))
1282                 vmw_fence_obj_unreference(&fence);
1283
1284         return 0;
1285 }
1286
1287 static int vmw_gb_surface_destroy(struct vmw_resource *res)
1288 {
1289         struct vmw_private *dev_priv = res->dev_priv;
1290         struct vmw_surface *srf = vmw_res_to_srf(res);
1291         struct {
1292                 SVGA3dCmdHeader header;
1293                 SVGA3dCmdDestroyGBSurface body;
1294         } *cmd;
1295
1296         if (likely(res->id == -1))
1297                 return 0;
1298
1299         mutex_lock(&dev_priv->binding_mutex);
1300         vmw_view_surface_list_destroy(dev_priv, &srf->view_list);
1301         vmw_binding_res_list_scrub(&res->binding_head);
1302
1303         cmd = VMW_CMD_RESERVE(dev_priv, sizeof(*cmd));
1304         if (unlikely(!cmd)) {
1305                 mutex_unlock(&dev_priv->binding_mutex);
1306                 return -ENOMEM;
1307         }
1308
1309         cmd->header.id = SVGA_3D_CMD_DESTROY_GB_SURFACE;
1310         cmd->header.size = sizeof(cmd->body);
1311         cmd->body.sid = res->id;
1312         vmw_cmd_commit(dev_priv, sizeof(*cmd));
1313         mutex_unlock(&dev_priv->binding_mutex);
1314         vmw_resource_release_id(res);
1315         vmw_fifo_resource_dec(dev_priv);
1316
1317         return 0;
1318 }
1319
1320 /**
1321  * vmw_gb_surface_define_ioctl - Ioctl function implementing
1322  * the user surface define functionality.
1323  *
1324  * @dev: Pointer to a struct drm_device.
1325  * @data: Pointer to data copied from / to user-space.
1326  * @file_priv: Pointer to a drm file private structure.
1327  */
1328 int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data,
1329                                 struct drm_file *file_priv)
1330 {
1331         union drm_vmw_gb_surface_create_arg *arg =
1332             (union drm_vmw_gb_surface_create_arg *)data;
1333         struct drm_vmw_gb_surface_create_rep *rep = &arg->rep;
1334         struct drm_vmw_gb_surface_create_ext_req req_ext;
1335
1336         req_ext.base = arg->req;
1337         req_ext.version = drm_vmw_gb_surface_v1;
1338         req_ext.svga3d_flags_upper_32_bits = 0;
1339         req_ext.multisample_pattern = SVGA3D_MS_PATTERN_NONE;
1340         req_ext.quality_level = SVGA3D_MS_QUALITY_NONE;
1341         req_ext.buffer_byte_stride = 0;
1342         req_ext.must_be_zero = 0;
1343
1344         return vmw_gb_surface_define_internal(dev, &req_ext, rep, file_priv);
1345 }
1346
1347 /**
1348  * vmw_gb_surface_reference_ioctl - Ioctl function implementing
1349  * the user surface reference functionality.
1350  *
1351  * @dev: Pointer to a struct drm_device.
1352  * @data: Pointer to data copied from / to user-space.
1353  * @file_priv: Pointer to a drm file private structure.
1354  */
1355 int vmw_gb_surface_reference_ioctl(struct drm_device *dev, void *data,
1356                                    struct drm_file *file_priv)
1357 {
1358         union drm_vmw_gb_surface_reference_arg *arg =
1359             (union drm_vmw_gb_surface_reference_arg *)data;
1360         struct drm_vmw_surface_arg *req = &arg->req;
1361         struct drm_vmw_gb_surface_ref_rep *rep = &arg->rep;
1362         struct drm_vmw_gb_surface_ref_ext_rep rep_ext;
1363         int ret;
1364
1365         ret = vmw_gb_surface_reference_internal(dev, req, &rep_ext, file_priv);
1366
1367         if (unlikely(ret != 0))
1368                 return ret;
1369
1370         rep->creq = rep_ext.creq.base;
1371         rep->crep = rep_ext.crep;
1372
1373         return ret;
1374 }
1375
1376 /**
1377  * vmw_gb_surface_define_ext_ioctl - Ioctl function implementing
1378  * the user surface define functionality.
1379  *
1380  * @dev: Pointer to a struct drm_device.
1381  * @data: Pointer to data copied from / to user-space.
1382  * @file_priv: Pointer to a drm file private structure.
1383  */
1384 int vmw_gb_surface_define_ext_ioctl(struct drm_device *dev, void *data,
1385                                 struct drm_file *file_priv)
1386 {
1387         union drm_vmw_gb_surface_create_ext_arg *arg =
1388             (union drm_vmw_gb_surface_create_ext_arg *)data;
1389         struct drm_vmw_gb_surface_create_ext_req *req = &arg->req;
1390         struct drm_vmw_gb_surface_create_rep *rep = &arg->rep;
1391
1392         return vmw_gb_surface_define_internal(dev, req, rep, file_priv);
1393 }
1394
1395 /**
1396  * vmw_gb_surface_reference_ext_ioctl - Ioctl function implementing
1397  * the user surface reference functionality.
1398  *
1399  * @dev: Pointer to a struct drm_device.
1400  * @data: Pointer to data copied from / to user-space.
1401  * @file_priv: Pointer to a drm file private structure.
1402  */
1403 int vmw_gb_surface_reference_ext_ioctl(struct drm_device *dev, void *data,
1404                                    struct drm_file *file_priv)
1405 {
1406         union drm_vmw_gb_surface_reference_ext_arg *arg =
1407             (union drm_vmw_gb_surface_reference_ext_arg *)data;
1408         struct drm_vmw_surface_arg *req = &arg->req;
1409         struct drm_vmw_gb_surface_ref_ext_rep *rep = &arg->rep;
1410
1411         return vmw_gb_surface_reference_internal(dev, req, rep, file_priv);
1412 }
1413
1414 /**
1415  * vmw_gb_surface_define_internal - Ioctl function implementing
1416  * the user surface define functionality.
1417  *
1418  * @dev: Pointer to a struct drm_device.
1419  * @req: Request argument from user-space.
1420  * @rep: Response argument to user-space.
1421  * @file_priv: Pointer to a drm file private structure.
1422  */
1423 static int
1424 vmw_gb_surface_define_internal(struct drm_device *dev,
1425                                struct drm_vmw_gb_surface_create_ext_req *req,
1426                                struct drm_vmw_gb_surface_create_rep *rep,
1427                                struct drm_file *file_priv)
1428 {
1429         struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
1430         struct vmw_private *dev_priv = vmw_priv(dev);
1431         struct vmw_user_surface *user_srf;
1432         struct vmw_surface_metadata metadata = {0};
1433         struct vmw_surface *srf;
1434         struct vmw_resource *res;
1435         struct vmw_resource *tmp;
1436         int ret = 0;
1437         uint32_t backup_handle = 0;
1438         SVGA3dSurfaceAllFlags svga3d_flags_64 =
1439                 SVGA3D_FLAGS_64(req->svga3d_flags_upper_32_bits,
1440                                 req->base.svga3d_flags);
1441
1442         /* array_size must be null for non-GL3 host. */
1443         if (req->base.array_size > 0 && !has_sm4_context(dev_priv)) {
1444                 VMW_DEBUG_USER("SM4 surface not supported.\n");
1445                 return -EINVAL;
1446         }
1447
1448         if (!has_sm4_1_context(dev_priv)) {
1449                 if (req->svga3d_flags_upper_32_bits != 0)
1450                         ret = -EINVAL;
1451
1452                 if (req->base.multisample_count != 0)
1453                         ret = -EINVAL;
1454
1455                 if (req->multisample_pattern != SVGA3D_MS_PATTERN_NONE)
1456                         ret = -EINVAL;
1457
1458                 if (req->quality_level != SVGA3D_MS_QUALITY_NONE)
1459                         ret = -EINVAL;
1460
1461                 if (ret) {
1462                         VMW_DEBUG_USER("SM4.1 surface not supported.\n");
1463                         return ret;
1464                 }
1465         }
1466
1467         if (req->buffer_byte_stride > 0 && !has_sm5_context(dev_priv)) {
1468                 VMW_DEBUG_USER("SM5 surface not supported.\n");
1469                 return -EINVAL;
1470         }
1471
1472         if ((svga3d_flags_64 & SVGA3D_SURFACE_MULTISAMPLE) &&
1473             req->base.multisample_count == 0) {
1474                 VMW_DEBUG_USER("Invalid sample count.\n");
1475                 return -EINVAL;
1476         }
1477
1478         if (req->base.mip_levels > DRM_VMW_MAX_MIP_LEVELS) {
1479                 VMW_DEBUG_USER("Invalid mip level.\n");
1480                 return -EINVAL;
1481         }
1482
1483         metadata.flags = svga3d_flags_64;
1484         metadata.format = req->base.format;
1485         metadata.mip_levels[0] = req->base.mip_levels;
1486         metadata.multisample_count = req->base.multisample_count;
1487         metadata.multisample_pattern = req->multisample_pattern;
1488         metadata.quality_level = req->quality_level;
1489         metadata.array_size = req->base.array_size;
1490         metadata.buffer_byte_stride = req->buffer_byte_stride;
1491         metadata.num_sizes = 1;
1492         metadata.base_size = req->base.base_size;
1493         metadata.scanout = req->base.drm_surface_flags &
1494                 drm_vmw_surface_flag_scanout;
1495
1496         /* Define a surface based on the parameters. */
1497         ret = vmw_gb_surface_define(dev_priv, &metadata, &srf);
1498         if (ret != 0) {
1499                 VMW_DEBUG_USER("Failed to define surface.\n");
1500                 return ret;
1501         }
1502
1503         user_srf = container_of(srf, struct vmw_user_surface, srf);
1504         if (drm_is_primary_client(file_priv))
1505                 user_srf->master = drm_file_get_master(file_priv);
1506
1507         res = &user_srf->srf.res;
1508
1509         if (req->base.buffer_handle != SVGA3D_INVALID_ID) {
1510                 ret = vmw_user_bo_lookup(file_priv, req->base.buffer_handle,
1511                                          &res->guest_memory_bo);
1512                 if (ret == 0) {
1513                         if (res->guest_memory_bo->tbo.base.size < res->guest_memory_size) {
1514                                 VMW_DEBUG_USER("Surface backup buffer too small.\n");
1515                                 vmw_bo_unreference(&res->guest_memory_bo);
1516                                 ret = -EINVAL;
1517                                 goto out_unlock;
1518                         } else {
1519                                 backup_handle = req->base.buffer_handle;
1520                         }
1521                 }
1522         } else if (req->base.drm_surface_flags &
1523                    (drm_vmw_surface_flag_create_buffer |
1524                     drm_vmw_surface_flag_coherent)) {
1525                 ret = vmw_gem_object_create_with_handle(dev_priv, file_priv,
1526                                                         res->guest_memory_size,
1527                                                         &backup_handle,
1528                                                         &res->guest_memory_bo);
1529                 if (ret == 0)
1530                         vmw_bo_reference(res->guest_memory_bo);
1531         }
1532
1533         if (unlikely(ret != 0)) {
1534                 vmw_resource_unreference(&res);
1535                 goto out_unlock;
1536         }
1537
1538         if (req->base.drm_surface_flags & drm_vmw_surface_flag_coherent) {
1539                 struct vmw_bo *backup = res->guest_memory_bo;
1540
1541                 ttm_bo_reserve(&backup->tbo, false, false, NULL);
1542                 if (!res->func->dirty_alloc)
1543                         ret = -EINVAL;
1544                 if (!ret)
1545                         ret = vmw_bo_dirty_add(backup);
1546                 if (!ret) {
1547                         res->coherent = true;
1548                         ret = res->func->dirty_alloc(res);
1549                 }
1550                 ttm_bo_unreserve(&backup->tbo);
1551                 if (ret) {
1552                         vmw_resource_unreference(&res);
1553                         goto out_unlock;
1554                 }
1555
1556         }
1557
1558         tmp = vmw_resource_reference(res);
1559         ret = ttm_prime_object_init(tfile, res->guest_memory_size, &user_srf->prime,
1560                                     req->base.drm_surface_flags &
1561                                     drm_vmw_surface_flag_shareable,
1562                                     VMW_RES_SURFACE,
1563                                     &vmw_user_surface_base_release);
1564
1565         if (unlikely(ret != 0)) {
1566                 vmw_resource_unreference(&tmp);
1567                 vmw_resource_unreference(&res);
1568                 goto out_unlock;
1569         }
1570
1571         rep->handle      = user_srf->prime.base.handle;
1572         rep->backup_size = res->guest_memory_size;
1573         if (res->guest_memory_bo) {
1574                 rep->buffer_map_handle =
1575                         drm_vma_node_offset_addr(&res->guest_memory_bo->tbo.base.vma_node);
1576                 rep->buffer_size = res->guest_memory_bo->tbo.base.size;
1577                 rep->buffer_handle = backup_handle;
1578         } else {
1579                 rep->buffer_map_handle = 0;
1580                 rep->buffer_size = 0;
1581                 rep->buffer_handle = SVGA3D_INVALID_ID;
1582         }
1583         vmw_resource_unreference(&res);
1584
1585 out_unlock:
1586         return ret;
1587 }
1588
1589 /**
1590  * vmw_gb_surface_reference_internal - Ioctl function implementing
1591  * the user surface reference functionality.
1592  *
1593  * @dev: Pointer to a struct drm_device.
1594  * @req: Pointer to user-space request surface arg.
1595  * @rep: Pointer to response to user-space.
1596  * @file_priv: Pointer to a drm file private structure.
1597  */
1598 static int
1599 vmw_gb_surface_reference_internal(struct drm_device *dev,
1600                                   struct drm_vmw_surface_arg *req,
1601                                   struct drm_vmw_gb_surface_ref_ext_rep *rep,
1602                                   struct drm_file *file_priv)
1603 {
1604         struct vmw_private *dev_priv = vmw_priv(dev);
1605         struct vmw_surface *srf;
1606         struct vmw_user_surface *user_srf;
1607         struct vmw_surface_metadata *metadata;
1608         struct ttm_base_object *base;
1609         u32 backup_handle;
1610         int ret;
1611
1612         ret = vmw_surface_handle_reference(dev_priv, file_priv, req->sid,
1613                                            req->handle_type, &base);
1614         if (unlikely(ret != 0))
1615                 return ret;
1616
1617         user_srf = container_of(base, struct vmw_user_surface, prime.base);
1618         srf = &user_srf->srf;
1619         if (!srf->res.guest_memory_bo) {
1620                 DRM_ERROR("Shared GB surface is missing a backup buffer.\n");
1621                 goto out_bad_resource;
1622         }
1623         metadata = &srf->metadata;
1624
1625         mutex_lock(&dev_priv->cmdbuf_mutex); /* Protect res->backup */
1626         ret = drm_gem_handle_create(file_priv, &srf->res.guest_memory_bo->tbo.base,
1627                                     &backup_handle);
1628         mutex_unlock(&dev_priv->cmdbuf_mutex);
1629         if (ret != 0) {
1630                 drm_err(dev, "Wasn't able to create a backing handle for surface sid = %u.\n",
1631                         req->sid);
1632                 goto out_bad_resource;
1633         }
1634
1635         rep->creq.base.svga3d_flags = SVGA3D_FLAGS_LOWER_32(metadata->flags);
1636         rep->creq.base.format = metadata->format;
1637         rep->creq.base.mip_levels = metadata->mip_levels[0];
1638         rep->creq.base.drm_surface_flags = 0;
1639         rep->creq.base.multisample_count = metadata->multisample_count;
1640         rep->creq.base.autogen_filter = metadata->autogen_filter;
1641         rep->creq.base.array_size = metadata->array_size;
1642         rep->creq.base.buffer_handle = backup_handle;
1643         rep->creq.base.base_size = metadata->base_size;
1644         rep->crep.handle = user_srf->prime.base.handle;
1645         rep->crep.backup_size = srf->res.guest_memory_size;
1646         rep->crep.buffer_handle = backup_handle;
1647         rep->crep.buffer_map_handle =
1648                 drm_vma_node_offset_addr(&srf->res.guest_memory_bo->tbo.base.vma_node);
1649         rep->crep.buffer_size = srf->res.guest_memory_bo->tbo.base.size;
1650
1651         rep->creq.version = drm_vmw_gb_surface_v1;
1652         rep->creq.svga3d_flags_upper_32_bits =
1653                 SVGA3D_FLAGS_UPPER_32(metadata->flags);
1654         rep->creq.multisample_pattern = metadata->multisample_pattern;
1655         rep->creq.quality_level = metadata->quality_level;
1656         rep->creq.must_be_zero = 0;
1657
1658 out_bad_resource:
1659         ttm_base_object_unref(&base);
1660
1661         return ret;
1662 }
1663
1664 /**
1665  * vmw_subres_dirty_add - Add a dirty region to a subresource
1666  * @dirty: The surfaces's dirty tracker.
1667  * @loc_start: The location corresponding to the start of the region.
1668  * @loc_end: The location corresponding to the end of the region.
1669  *
1670  * As we are assuming that @loc_start and @loc_end represent a sequential
1671  * range of backing store memory, if the region spans multiple lines then
1672  * regardless of the x coordinate, the full lines are dirtied.
1673  * Correspondingly if the region spans multiple z slices, then full rather
1674  * than partial z slices are dirtied.
1675  */
1676 static void vmw_subres_dirty_add(struct vmw_surface_dirty *dirty,
1677                                  const struct vmw_surface_loc *loc_start,
1678                                  const struct vmw_surface_loc *loc_end)
1679 {
1680         const struct vmw_surface_cache *cache = &dirty->cache;
1681         SVGA3dBox *box = &dirty->boxes[loc_start->sub_resource];
1682         u32 mip = loc_start->sub_resource % cache->num_mip_levels;
1683         const struct drm_vmw_size *size = &cache->mip[mip].size;
1684         u32 box_c2 = box->z + box->d;
1685
1686         if (WARN_ON(loc_start->sub_resource >= dirty->num_subres))
1687                 return;
1688
1689         if (box->d == 0 || box->z > loc_start->z)
1690                 box->z = loc_start->z;
1691         if (box_c2 < loc_end->z)
1692                 box->d = loc_end->z - box->z;
1693
1694         if (loc_start->z + 1 == loc_end->z) {
1695                 box_c2 = box->y + box->h;
1696                 if (box->h == 0 || box->y > loc_start->y)
1697                         box->y = loc_start->y;
1698                 if (box_c2 < loc_end->y)
1699                         box->h = loc_end->y - box->y;
1700
1701                 if (loc_start->y + 1 == loc_end->y) {
1702                         box_c2 = box->x + box->w;
1703                         if (box->w == 0 || box->x > loc_start->x)
1704                                 box->x = loc_start->x;
1705                         if (box_c2 < loc_end->x)
1706                                 box->w = loc_end->x - box->x;
1707                 } else {
1708                         box->x = 0;
1709                         box->w = size->width;
1710                 }
1711         } else {
1712                 box->y = 0;
1713                 box->h = size->height;
1714                 box->x = 0;
1715                 box->w = size->width;
1716         }
1717 }
1718
1719 /**
1720  * vmw_subres_dirty_full - Mark a full subresource as dirty
1721  * @dirty: The surface's dirty tracker.
1722  * @subres: The subresource
1723  */
1724 static void vmw_subres_dirty_full(struct vmw_surface_dirty *dirty, u32 subres)
1725 {
1726         const struct vmw_surface_cache *cache = &dirty->cache;
1727         u32 mip = subres % cache->num_mip_levels;
1728         const struct drm_vmw_size *size = &cache->mip[mip].size;
1729         SVGA3dBox *box = &dirty->boxes[subres];
1730
1731         box->x = 0;
1732         box->y = 0;
1733         box->z = 0;
1734         box->w = size->width;
1735         box->h = size->height;
1736         box->d = size->depth;
1737 }
1738
1739 /*
1740  * vmw_surface_tex_dirty_add_range - The dirty_add_range callback for texture
1741  * surfaces.
1742  */
1743 static void vmw_surface_tex_dirty_range_add(struct vmw_resource *res,
1744                                             size_t start, size_t end)
1745 {
1746         struct vmw_surface_dirty *dirty =
1747                 (struct vmw_surface_dirty *) res->dirty;
1748         size_t backup_end = res->guest_memory_offset + res->guest_memory_size;
1749         struct vmw_surface_loc loc1, loc2;
1750         const struct vmw_surface_cache *cache;
1751
1752         start = max_t(size_t, start, res->guest_memory_offset) - res->guest_memory_offset;
1753         end = min(end, backup_end) - res->guest_memory_offset;
1754         cache = &dirty->cache;
1755         vmw_surface_get_loc(cache, &loc1, start);
1756         vmw_surface_get_loc(cache, &loc2, end - 1);
1757         vmw_surface_inc_loc(cache, &loc2);
1758
1759         if (loc1.sheet != loc2.sheet) {
1760                 u32 sub_res;
1761
1762                 /*
1763                  * Multiple multisample sheets. To do this in an optimized
1764                  * fashion, compute the dirty region for each sheet and the
1765                  * resulting union. Since this is not a common case, just dirty
1766                  * the whole surface.
1767                  */
1768                 for (sub_res = 0; sub_res < dirty->num_subres; ++sub_res)
1769                         vmw_subres_dirty_full(dirty, sub_res);
1770                 return;
1771         }
1772         if (loc1.sub_resource + 1 == loc2.sub_resource) {
1773                 /* Dirty range covers a single sub-resource */
1774                 vmw_subres_dirty_add(dirty, &loc1, &loc2);
1775         } else {
1776                 /* Dirty range covers multiple sub-resources */
1777                 struct vmw_surface_loc loc_min, loc_max;
1778                 u32 sub_res;
1779
1780                 vmw_surface_max_loc(cache, loc1.sub_resource, &loc_max);
1781                 vmw_subres_dirty_add(dirty, &loc1, &loc_max);
1782                 vmw_surface_min_loc(cache, loc2.sub_resource - 1, &loc_min);
1783                 vmw_subres_dirty_add(dirty, &loc_min, &loc2);
1784                 for (sub_res = loc1.sub_resource + 1;
1785                      sub_res < loc2.sub_resource - 1; ++sub_res)
1786                         vmw_subres_dirty_full(dirty, sub_res);
1787         }
1788 }
1789
1790 /*
1791  * vmw_surface_tex_dirty_add_range - The dirty_add_range callback for buffer
1792  * surfaces.
1793  */
1794 static void vmw_surface_buf_dirty_range_add(struct vmw_resource *res,
1795                                             size_t start, size_t end)
1796 {
1797         struct vmw_surface_dirty *dirty =
1798                 (struct vmw_surface_dirty *) res->dirty;
1799         const struct vmw_surface_cache *cache = &dirty->cache;
1800         size_t backup_end = res->guest_memory_offset + cache->mip_chain_bytes;
1801         SVGA3dBox *box = &dirty->boxes[0];
1802         u32 box_c2;
1803
1804         box->h = box->d = 1;
1805         start = max_t(size_t, start, res->guest_memory_offset) - res->guest_memory_offset;
1806         end = min(end, backup_end) - res->guest_memory_offset;
1807         box_c2 = box->x + box->w;
1808         if (box->w == 0 || box->x > start)
1809                 box->x = start;
1810         if (box_c2 < end)
1811                 box->w = end - box->x;
1812 }
1813
1814 /*
1815  * vmw_surface_tex_dirty_add_range - The dirty_add_range callback for surfaces
1816  */
1817 static void vmw_surface_dirty_range_add(struct vmw_resource *res, size_t start,
1818                                         size_t end)
1819 {
1820         struct vmw_surface *srf = vmw_res_to_srf(res);
1821
1822         if (WARN_ON(end <= res->guest_memory_offset ||
1823                     start >= res->guest_memory_offset + res->guest_memory_size))
1824                 return;
1825
1826         if (srf->metadata.format == SVGA3D_BUFFER)
1827                 vmw_surface_buf_dirty_range_add(res, start, end);
1828         else
1829                 vmw_surface_tex_dirty_range_add(res, start, end);
1830 }
1831
1832 /*
1833  * vmw_surface_dirty_sync - The surface's dirty_sync callback.
1834  */
1835 static int vmw_surface_dirty_sync(struct vmw_resource *res)
1836 {
1837         struct vmw_private *dev_priv = res->dev_priv;
1838         u32 i, num_dirty;
1839         struct vmw_surface_dirty *dirty =
1840                 (struct vmw_surface_dirty *) res->dirty;
1841         size_t alloc_size;
1842         const struct vmw_surface_cache *cache = &dirty->cache;
1843         struct {
1844                 SVGA3dCmdHeader header;
1845                 SVGA3dCmdDXUpdateSubResource body;
1846         } *cmd1;
1847         struct {
1848                 SVGA3dCmdHeader header;
1849                 SVGA3dCmdUpdateGBImage body;
1850         } *cmd2;
1851         void *cmd;
1852
1853         num_dirty = 0;
1854         for (i = 0; i < dirty->num_subres; ++i) {
1855                 const SVGA3dBox *box = &dirty->boxes[i];
1856
1857                 if (box->d)
1858                         num_dirty++;
1859         }
1860
1861         if (!num_dirty)
1862                 goto out;
1863
1864         alloc_size = num_dirty * ((has_sm4_context(dev_priv)) ? sizeof(*cmd1) : sizeof(*cmd2));
1865         cmd = VMW_CMD_RESERVE(dev_priv, alloc_size);
1866         if (!cmd)
1867                 return -ENOMEM;
1868
1869         cmd1 = cmd;
1870         cmd2 = cmd;
1871
1872         for (i = 0; i < dirty->num_subres; ++i) {
1873                 const SVGA3dBox *box = &dirty->boxes[i];
1874
1875                 if (!box->d)
1876                         continue;
1877
1878                 /*
1879                  * DX_UPDATE_SUBRESOURCE is aware of array surfaces.
1880                  * UPDATE_GB_IMAGE is not.
1881                  */
1882                 if (has_sm4_context(dev_priv)) {
1883                         cmd1->header.id = SVGA_3D_CMD_DX_UPDATE_SUBRESOURCE;
1884                         cmd1->header.size = sizeof(cmd1->body);
1885                         cmd1->body.sid = res->id;
1886                         cmd1->body.subResource = i;
1887                         cmd1->body.box = *box;
1888                         cmd1++;
1889                 } else {
1890                         cmd2->header.id = SVGA_3D_CMD_UPDATE_GB_IMAGE;
1891                         cmd2->header.size = sizeof(cmd2->body);
1892                         cmd2->body.image.sid = res->id;
1893                         cmd2->body.image.face = i / cache->num_mip_levels;
1894                         cmd2->body.image.mipmap = i -
1895                                 (cache->num_mip_levels * cmd2->body.image.face);
1896                         cmd2->body.box = *box;
1897                         cmd2++;
1898                 }
1899
1900         }
1901         vmw_cmd_commit(dev_priv, alloc_size);
1902  out:
1903         memset(&dirty->boxes[0], 0, sizeof(dirty->boxes[0]) *
1904                dirty->num_subres);
1905
1906         return 0;
1907 }
1908
1909 /*
1910  * vmw_surface_dirty_alloc - The surface's dirty_alloc callback.
1911  */
1912 static int vmw_surface_dirty_alloc(struct vmw_resource *res)
1913 {
1914         struct vmw_surface *srf = vmw_res_to_srf(res);
1915         const struct vmw_surface_metadata *metadata = &srf->metadata;
1916         struct vmw_surface_dirty *dirty;
1917         u32 num_layers = 1;
1918         u32 num_mip;
1919         u32 num_subres;
1920         u32 num_samples;
1921         size_t dirty_size;
1922         int ret;
1923
1924         if (metadata->array_size)
1925                 num_layers = metadata->array_size;
1926         else if (metadata->flags & SVGA3D_SURFACE_CUBEMAP)
1927                 num_layers *= SVGA3D_MAX_SURFACE_FACES;
1928
1929         num_mip = metadata->mip_levels[0];
1930         if (!num_mip)
1931                 num_mip = 1;
1932
1933         num_subres = num_layers * num_mip;
1934         dirty_size = struct_size(dirty, boxes, num_subres);
1935
1936         dirty = kvzalloc(dirty_size, GFP_KERNEL);
1937         if (!dirty) {
1938                 ret = -ENOMEM;
1939                 goto out_no_dirty;
1940         }
1941
1942         num_samples = max_t(u32, 1, metadata->multisample_count);
1943         ret = vmw_surface_setup_cache(&metadata->base_size, metadata->format,
1944                                       num_mip, num_layers, num_samples,
1945                                       &dirty->cache);
1946         if (ret)
1947                 goto out_no_cache;
1948
1949         dirty->num_subres = num_subres;
1950         res->dirty = (struct vmw_resource_dirty *) dirty;
1951
1952         return 0;
1953
1954 out_no_cache:
1955         kvfree(dirty);
1956 out_no_dirty:
1957         return ret;
1958 }
1959
1960 /*
1961  * vmw_surface_dirty_free - The surface's dirty_free callback
1962  */
1963 static void vmw_surface_dirty_free(struct vmw_resource *res)
1964 {
1965         struct vmw_surface_dirty *dirty =
1966                 (struct vmw_surface_dirty *) res->dirty;
1967
1968         kvfree(dirty);
1969         res->dirty = NULL;
1970 }
1971
1972 /*
1973  * vmw_surface_clean - The surface's clean callback
1974  */
1975 static int vmw_surface_clean(struct vmw_resource *res)
1976 {
1977         struct vmw_private *dev_priv = res->dev_priv;
1978         size_t alloc_size;
1979         struct {
1980                 SVGA3dCmdHeader header;
1981                 SVGA3dCmdReadbackGBSurface body;
1982         } *cmd;
1983
1984         alloc_size = sizeof(*cmd);
1985         cmd = VMW_CMD_RESERVE(dev_priv, alloc_size);
1986         if (!cmd)
1987                 return -ENOMEM;
1988
1989         cmd->header.id = SVGA_3D_CMD_READBACK_GB_SURFACE;
1990         cmd->header.size = sizeof(cmd->body);
1991         cmd->body.sid = res->id;
1992         vmw_cmd_commit(dev_priv, alloc_size);
1993
1994         return 0;
1995 }
1996
1997 /*
1998  * vmw_gb_surface_define - Define a private GB surface
1999  *
2000  * @dev_priv: Pointer to a device private.
2001  * @metadata: Metadata representing the surface to create.
2002  * @user_srf_out: allocated user_srf. Set to NULL on failure.
2003  *
2004  * GB surfaces allocated by this function will not have a user mode handle, and
2005  * thus will only be visible to vmwgfx.  For optimization reasons the
2006  * surface may later be given a user mode handle by another function to make
2007  * it available to user mode drivers.
2008  */
2009 int vmw_gb_surface_define(struct vmw_private *dev_priv,
2010                           const struct vmw_surface_metadata *req,
2011                           struct vmw_surface **srf_out)
2012 {
2013         struct vmw_surface_metadata *metadata;
2014         struct vmw_user_surface *user_srf;
2015         struct vmw_surface *srf;
2016         u32 sample_count = 1;
2017         u32 num_layers = 1;
2018         int ret;
2019
2020         *srf_out = NULL;
2021
2022         if (req->scanout) {
2023                 if (!vmw_surface_is_screen_target_format(req->format)) {
2024                         VMW_DEBUG_USER("Invalid Screen Target surface format.");
2025                         return -EINVAL;
2026                 }
2027
2028                 if (req->base_size.width > dev_priv->texture_max_width ||
2029                     req->base_size.height > dev_priv->texture_max_height) {
2030                         VMW_DEBUG_USER("%ux%u\n, exceed max surface size %ux%u",
2031                                        req->base_size.width,
2032                                        req->base_size.height,
2033                                        dev_priv->texture_max_width,
2034                                        dev_priv->texture_max_height);
2035                         return -EINVAL;
2036                 }
2037         } else {
2038                 const SVGA3dSurfaceDesc *desc =
2039                         vmw_surface_get_desc(req->format);
2040
2041                 if (desc->blockDesc == SVGA3DBLOCKDESC_NONE) {
2042                         VMW_DEBUG_USER("Invalid surface format.\n");
2043                         return -EINVAL;
2044                 }
2045         }
2046
2047         if (req->autogen_filter != SVGA3D_TEX_FILTER_NONE)
2048                 return -EINVAL;
2049
2050         if (req->num_sizes != 1)
2051                 return -EINVAL;
2052
2053         if (req->sizes != NULL)
2054                 return -EINVAL;
2055
2056         user_srf = kzalloc(sizeof(*user_srf), GFP_KERNEL);
2057         if (unlikely(!user_srf)) {
2058                 ret = -ENOMEM;
2059                 goto out_unlock;
2060         }
2061
2062         *srf_out  = &user_srf->srf;
2063         user_srf->prime.base.shareable = false;
2064         user_srf->prime.base.tfile = NULL;
2065
2066         srf = &user_srf->srf;
2067         srf->metadata = *req;
2068         srf->offsets = NULL;
2069
2070         metadata = &srf->metadata;
2071
2072         if (metadata->array_size)
2073                 num_layers = req->array_size;
2074         else if (metadata->flags & SVGA3D_SURFACE_CUBEMAP)
2075                 num_layers = SVGA3D_MAX_SURFACE_FACES;
2076
2077         if (metadata->flags & SVGA3D_SURFACE_MULTISAMPLE)
2078                 sample_count = metadata->multisample_count;
2079
2080         srf->res.guest_memory_size =
2081                 vmw_surface_get_serialized_size_extended(
2082                                 metadata->format,
2083                                 metadata->base_size,
2084                                 metadata->mip_levels[0],
2085                                 num_layers,
2086                                 sample_count);
2087
2088         if (metadata->flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT)
2089                 srf->res.guest_memory_size += sizeof(SVGA3dDXSOState);
2090
2091         /*
2092          * Don't set SVGA3D_SURFACE_SCREENTARGET flag for a scanout surface with
2093          * size greater than STDU max width/height. This is really a workaround
2094          * to support creation of big framebuffer requested by some user-space
2095          * for whole topology. That big framebuffer won't really be used for
2096          * binding with screen target as during prepare_fb a separate surface is
2097          * created so it's safe to ignore SVGA3D_SURFACE_SCREENTARGET flag.
2098          */
2099         if (dev_priv->active_display_unit == vmw_du_screen_target &&
2100             metadata->scanout &&
2101             metadata->base_size.width <= dev_priv->stdu_max_width &&
2102             metadata->base_size.height <= dev_priv->stdu_max_height)
2103                 metadata->flags |= SVGA3D_SURFACE_SCREENTARGET;
2104
2105         /*
2106          * From this point, the generic resource management functions
2107          * destroy the object on failure.
2108          */
2109         ret = vmw_surface_init(dev_priv, srf, vmw_user_surface_free);
2110
2111         return ret;
2112
2113 out_unlock:
2114         return ret;
2115 }