13192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/**********************************************************
2e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul * Copyright 2009-2015 VMware, Inc.  All rights reserved.
33192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
43192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Permission is hereby granted, free of charge, to any person
53192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * obtaining a copy of this software and associated documentation
63192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * files (the "Software"), to deal in the Software without
73192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * restriction, including without limitation the rights to use, copy,
83192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * modify, merge, publish, distribute, sublicense, and/or sell copies
93192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * of the Software, and to permit persons to whom the Software is
103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * furnished to do so, subject to the following conditions:
113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * The above copyright notice and this permission notice shall be
133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * included in all copies or substantial portions of the Software.
143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * SOFTWARE.
233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz **********************************************************/
253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/**
273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * @file
283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Wrappers for DRM ioctl functionlaity used by the rest of the vmw
303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * drm winsys.
313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Based on svgaicd_escape.c
333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_cmd.h"
373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "util/u_memory.h"
383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "util/u_math.h"
393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svgadump/svga_dump.h"
402f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom#include "state_tracker/drm_driver.h"
413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "vmw_screen.h"
423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "vmw_context.h"
43e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom#include "vmw_fence.h"
443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "xf86drm.h"
453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "vmwgfx_drm.h"
46e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom#include "svga3d_caps.h"
47fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul#include "svga3d_reg.h"
483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
491284d5b25507a56634519ac385cbc00a00b94417Chia-I Wu#include "os/os_mman.h"
501284d5b25507a56634519ac385cbc00a00b94417Chia-I Wu
513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include <errno.h>
523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include <unistd.h>
533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
540c065270c0ff063edba03516b22d734023cac912Charmaine Lee#define VMW_MAX_DEFAULT_TEXTURE_SIZE   (128 * 1024 * 1024)
55395c7b8fa17069fe996a63a8bca2bfd0fe3f16a0Thomas Hellstrom#define VMW_FENCE_TIMEOUT_SECONDS 60
560c065270c0ff063edba03516b22d734023cac912Charmaine Lee
573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct vmw_region
583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   uint32_t handle;
603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   uint64_t map_handle;
613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   void *data;
623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   uint32_t map_count;
633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int drm_fd;
643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   uint32_t size;
653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz};
663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
67fe6a854477c2ed30c37c200668a4dc86512120f7Brian Pauluint32_t
68fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulvmw_region_size(struct vmw_region *region)
69fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul{
70fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   return region->size;
71fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul}
72fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzuint32
743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_ioctl_context_create(struct vmw_winsys_screen *vws)
753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct drm_vmw_context_arg c_arg;
773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int ret;
783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   VMW_FUNC;
803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   ret = drmCommandRead(vws->ioctl.drm_fd, DRM_VMW_CREATE_CONTEXT,
823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz			&c_arg, sizeof(c_arg));
833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (ret)
853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return -1;
863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vmw_printf("Context id is %d\n", c_arg.cid);
883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return c_arg.cid;
893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
91e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Pauluint32
92e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paulvmw_ioctl_extended_context_create(struct vmw_winsys_screen *vws,
93e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul                                  boolean vgpu10)
94e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul{
95e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   union drm_vmw_extended_context_arg c_arg;
96e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   int ret;
97e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul
98e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   VMW_FUNC;
99e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   memset(&c_arg, 0, sizeof(c_arg));
100e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   c_arg.req = (vgpu10 ? drm_vmw_context_vgpu10 : drm_vmw_context_legacy);
101e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   ret = drmCommandWriteRead(vws->ioctl.drm_fd,
102e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul                             DRM_VMW_CREATE_EXTENDED_CONTEXT,
103e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul                             &c_arg, sizeof(c_arg));
104e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul
105e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   if (ret)
106e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul      return -1;
107e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul
108e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   vmw_printf("Context id is %d\n", c_arg.cid);
109e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   return c_arg.rep.cid;
110e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul}
111e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul
1123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvoid
1133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_ioctl_context_destroy(struct vmw_winsys_screen *vws, uint32 cid)
1143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct drm_vmw_context_arg c_arg;
1163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   VMW_FUNC;
1183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   memset(&c_arg, 0, sizeof(c_arg));
1203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   c_arg.cid = cid;
1213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   (void)drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_UNREF_CONTEXT,
1233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz			 &c_arg, sizeof(c_arg));
1243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
1263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzuint32
1283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_ioctl_surface_create(struct vmw_winsys_screen *vws,
129141e39a8936a7b19fd857a35ea2d200daf1777c7Thomas Hellstrom                         SVGA3dSurfaceFlags flags,
130141e39a8936a7b19fd857a35ea2d200daf1777c7Thomas Hellstrom                         SVGA3dSurfaceFormat format,
131141e39a8936a7b19fd857a35ea2d200daf1777c7Thomas Hellstrom                         unsigned usage,
132141e39a8936a7b19fd857a35ea2d200daf1777c7Thomas Hellstrom                         SVGA3dSize size,
133e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul                         uint32_t numFaces, uint32_t numMipLevels,
134e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul                         unsigned sampleCount)
1353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   union drm_vmw_surface_create_arg s_arg;
1373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct drm_vmw_surface_create_req *req = &s_arg.req;
1383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct drm_vmw_surface_arg *rep = &s_arg.rep;
1393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct drm_vmw_size sizes[DRM_VMW_MAX_SURFACE_FACES*
1403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz			     DRM_VMW_MAX_MIP_LEVELS];
1413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct drm_vmw_size *cur_size;
1423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   uint32_t iFace;
1433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   uint32_t iMipLevel;
1443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int ret;
1453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vmw_printf("%s flags %d format %d\n", __FUNCTION__, flags, format);
1473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   memset(&s_arg, 0, sizeof(s_arg));
149e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   req->flags = (uint32_t) flags;
150e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   req->scanout = !!(usage & SVGA_SURFACE_USAGE_SCANOUT);
1513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   req->format = (uint32_t) format;
152141e39a8936a7b19fd857a35ea2d200daf1777c7Thomas Hellstrom   req->shareable = !!(usage & SVGA_SURFACE_USAGE_SHARED);
1533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(numFaces * numMipLevels < DRM_VMW_MAX_SURFACE_FACES*
1553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz	  DRM_VMW_MAX_MIP_LEVELS);
1563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   cur_size = sizes;
1573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (iFace = 0; iFace < numFaces; ++iFace) {
1583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dSize mipSize = size;
1593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      req->mip_levels[iFace] = numMipLevels;
1613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      for (iMipLevel = 0; iMipLevel < numMipLevels; ++iMipLevel) {
1623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz	 cur_size->width = mipSize.width;
1633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz	 cur_size->height = mipSize.height;
1643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz	 cur_size->depth = mipSize.depth;
1653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz	 mipSize.width = MAX2(mipSize.width >> 1, 1);
1663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz	 mipSize.height = MAX2(mipSize.height >> 1, 1);
1673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz	 mipSize.depth = MAX2(mipSize.depth >> 1, 1);
1683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz	 cur_size++;
1693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
1703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
1713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (iFace = numFaces; iFace < SVGA3D_MAX_SURFACE_FACES; ++iFace) {
1723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      req->mip_levels[iFace] = 0;
1733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
1743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   req->size_addr = (unsigned long)&sizes;
1763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_CREATE_SURFACE,
1783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz			     &s_arg, sizeof(s_arg));
1793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (ret)
1813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return -1;
1823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vmw_printf("Surface id is %d\n", rep->sid);
1843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return rep->sid;
1863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
1873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
188fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
189fe6a854477c2ed30c37c200668a4dc86512120f7Brian Pauluint32
190fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulvmw_ioctl_gb_surface_create(struct vmw_winsys_screen *vws,
191fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul			    SVGA3dSurfaceFlags flags,
192fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul			    SVGA3dSurfaceFormat format,
193141e39a8936a7b19fd857a35ea2d200daf1777c7Thomas Hellstrom                            unsigned usage,
194fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul			    SVGA3dSize size,
195fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul			    uint32_t numFaces,
196fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul			    uint32_t numMipLevels,
197e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul                            unsigned sampleCount,
198fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul                            uint32_t buffer_handle,
199fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul			    struct vmw_region **p_region)
200fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul{
201fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   union drm_vmw_gb_surface_create_arg s_arg;
202fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   struct drm_vmw_gb_surface_create_req *req = &s_arg.req;
203fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   struct drm_vmw_gb_surface_create_rep *rep = &s_arg.rep;
204fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   struct vmw_region *region = NULL;
205fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   int ret;
206fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
207fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   vmw_printf("%s flags %d format %d\n", __FUNCTION__, flags, format);
208fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
209fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   if (p_region) {
210fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      region = CALLOC_STRUCT(vmw_region);
211fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      if (!region)
212fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul         return SVGA3D_INVALID_ID;
213fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   }
214fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
215fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   memset(&s_arg, 0, sizeof(s_arg));
216e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   req->svga3d_flags = (uint32_t) flags;
217e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   if (usage & SVGA_SURFACE_USAGE_SCANOUT)
218e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul      req->drm_surface_flags |= drm_vmw_surface_flag_scanout;
219fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   req->format = (uint32_t) format;
220141e39a8936a7b19fd857a35ea2d200daf1777c7Thomas Hellstrom   if (usage & SVGA_SURFACE_USAGE_SHARED)
221141e39a8936a7b19fd857a35ea2d200daf1777c7Thomas Hellstrom      req->drm_surface_flags |= drm_vmw_surface_flag_shareable;
222fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   req->drm_surface_flags |= drm_vmw_surface_flag_create_buffer;
223fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   req->base_size.width = size.width;
224fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   req->base_size.height = size.height;
225fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   req->base_size.depth = size.depth;
226fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   req->mip_levels = numMipLevels;
227fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   req->multisample_count = 0;
228fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   req->autogen_filter = SVGA3D_TEX_FILTER_NONE;
229e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul
230e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   if (vws->base.have_vgpu10) {
231e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul      req->array_size = numFaces;
232e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul      req->multisample_count = sampleCount;
233e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   } else {
234e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul      assert(numFaces * numMipLevels < DRM_VMW_MAX_SURFACE_FACES*
235e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul	     DRM_VMW_MAX_MIP_LEVELS);
236e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul      req->array_size = 0;
237e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   }
238e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul
239fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   if (buffer_handle)
240fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      req->buffer_handle = buffer_handle;
241fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   else
242fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      req->buffer_handle = SVGA3D_INVALID_ID;
243fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
244fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GB_SURFACE_CREATE,
245fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul			     &s_arg, sizeof(s_arg));
246fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
247fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   if (ret)
248fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      goto out_fail_create;
249fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
250fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   if (p_region) {
251fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      region->handle = rep->buffer_handle;
252fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      region->map_handle = rep->buffer_map_handle;
253fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      region->drm_fd = vws->ioctl.drm_fd;
254fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      region->size = rep->backup_size;
255fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      *p_region = region;
256fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   }
257fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
258fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   vmw_printf("Surface id is %d\n", rep->sid);
259fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   return rep->handle;
260fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
261fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulout_fail_create:
2629019e5e19532fe214fc6e45b9ee1f60bbe332456Matt Turner   FREE(region);
263fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   return SVGA3D_INVALID_ID;
264fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul}
265fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
266fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul/**
2672f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom * vmw_ioctl_surface_req - Fill in a struct surface_req
2682f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom *
2692f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom * @vws: Winsys screen
2702f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom * @whandle: Surface handle
2712f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom * @req: The struct surface req to fill in
2722f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom * @needs_unref: This call takes a kernel surface reference that needs to
2732f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom * be unreferenced.
2742f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom *
2752f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom * Returns 0 on success, negative error type otherwise.
2762f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom * Fills in the surface_req structure according to handle type and kernel
2772f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom * capabilities.
2782f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom */
2792f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstromstatic int
2802f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstromvmw_ioctl_surface_req(const struct vmw_winsys_screen *vws,
2812f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom                      const struct winsys_handle *whandle,
2822f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom                      struct drm_vmw_surface_arg *req,
2832f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom                      boolean *needs_unref)
2842f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom{
2852f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom   int ret;
2862f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom
2872f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom   switch(whandle->type) {
2882f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom   case DRM_API_HANDLE_TYPE_SHARED:
2892f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom   case DRM_API_HANDLE_TYPE_KMS:
2902f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom      *needs_unref = FALSE;
2912f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom      req->handle_type = DRM_VMW_HANDLE_LEGACY;
2922f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom      req->sid = whandle->handle;
2932f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom      break;
2942f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom   case DRM_API_HANDLE_TYPE_FD:
2952f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom      if (!vws->ioctl.have_drm_2_6) {
2962f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom         uint32_t handle;
2972f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom
2982f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom         ret = drmPrimeFDToHandle(vws->ioctl.drm_fd, whandle->handle, &handle);
2992f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom         if (ret) {
3002f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom            vmw_error("Failed to get handle from prime fd %d.\n",
3012f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom                      (int) whandle->handle);
3022f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom            return -EINVAL;
3032f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom         }
3042f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom
3052f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom         *needs_unref = TRUE;
3062f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom         req->handle_type = DRM_VMW_HANDLE_LEGACY;
3072f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom         req->sid = handle;
3082f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom      } else {
3092f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom         *needs_unref = FALSE;
3102f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom         req->handle_type = DRM_VMW_HANDLE_PRIME;
3112f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom         req->sid = whandle->handle;
3122f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom      }
3132f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom      break;
3142f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom   default:
3152f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom      vmw_error("Attempt to import unsupported handle type %d.\n",
3162f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom                whandle->type);
3172f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom      return -EINVAL;
3182f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom   }
3192f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom
3202f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom   return 0;
3212f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom}
3222f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom
3232f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom/**
324fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * vmw_ioctl_gb_surface_ref - Put a reference on a guest-backed surface and
325fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * get surface information
326fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul *
327fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @vws: Screen to register the reference on
328fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @handle: Kernel handle of the guest-backed surface
329fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @flags: flags used when the surface was created
330fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @format: Format used when the surface was created
331fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @numMipLevels: Number of mipmap levels of the surface
332fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @p_region: On successful return points to a newly allocated
333fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * struct vmw_region holding a reference to the surface backup buffer.
334fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul *
335fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * Returns 0 on success, a system error on failure.
336fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul */
337fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulint
338fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulvmw_ioctl_gb_surface_ref(struct vmw_winsys_screen *vws,
3392f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom                         const struct winsys_handle *whandle,
340fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul                         SVGA3dSurfaceFlags *flags,
341fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul                         SVGA3dSurfaceFormat *format,
342fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul                         uint32_t *numMipLevels,
3432f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom                         uint32_t *handle,
344fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul                         struct vmw_region **p_region)
345fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul{
346fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   union drm_vmw_gb_surface_reference_arg s_arg;
347fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   struct drm_vmw_surface_arg *req = &s_arg.req;
348fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   struct drm_vmw_gb_surface_ref_rep *rep = &s_arg.rep;
349fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   struct vmw_region *region = NULL;
3502f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom   boolean needs_unref = FALSE;
351fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   int ret;
352fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
353fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   vmw_printf("%s flags %d format %d\n", __FUNCTION__, flags, format);
354fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
355fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   assert(p_region != NULL);
356fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   region = CALLOC_STRUCT(vmw_region);
357fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   if (!region)
358fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      return -ENOMEM;
359fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
360fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   memset(&s_arg, 0, sizeof(s_arg));
3612f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom   ret = vmw_ioctl_surface_req(vws, whandle, req, &needs_unref);
3622f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom   if (ret)
3632f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom      goto out_fail_req;
364fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
3652f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom   *handle = req->sid;
366fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GB_SURFACE_REF,
367fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul			     &s_arg, sizeof(s_arg));
368fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
369fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   if (ret)
370fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      goto out_fail_ref;
371fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
372fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   region->handle = rep->crep.buffer_handle;
373fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   region->map_handle = rep->crep.buffer_map_handle;
374fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   region->drm_fd = vws->ioctl.drm_fd;
375fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   region->size = rep->crep.backup_size;
376fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   *p_region = region;
377fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
3782f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom   *handle = rep->crep.handle;
379fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   *flags = rep->creq.svga3d_flags;
380fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   *format = rep->creq.format;
381fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   *numMipLevels = rep->creq.mip_levels;
382fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
3832f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom   if (needs_unref)
3842f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom      vmw_ioctl_surface_destroy(vws, *handle);
3852f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom
386fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   return 0;
387fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulout_fail_ref:
3882f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom   if (needs_unref)
3892f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom      vmw_ioctl_surface_destroy(vws, *handle);
3902f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstromout_fail_req:
3919019e5e19532fe214fc6e45b9ee1f60bbe332456Matt Turner   FREE(region);
392fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   return ret;
393fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul}
394fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
3953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvoid
3963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws, uint32 sid)
3973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
3983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct drm_vmw_surface_arg s_arg;
3993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   VMW_FUNC;
4013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   memset(&s_arg, 0, sizeof(s_arg));
4033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   s_arg.sid = sid;
4043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   (void)drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_UNREF_SURFACE,
4063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz			 &s_arg, sizeof(s_arg));
4073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
4083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvoid
410d12f2bb9c03a9e8a08824c849200f5b23c05914cThomas Hellstromvmw_ioctl_command(struct vmw_winsys_screen *vws, int32_t cid,
411d12f2bb9c03a9e8a08824c849200f5b23c05914cThomas Hellstrom		  uint32_t throttle_us, void *commands, uint32_t size,
412e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom		  struct pipe_fence_handle **pfence)
4133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
4143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct drm_vmw_execbuf_arg arg;
4153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct drm_vmw_fence_rep rep;
4163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int ret;
417e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   int argsize;
4183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#ifdef DEBUG
4203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   {
4213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      static boolean firsttime = TRUE;
4223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      static boolean debug = FALSE;
4233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      static boolean skip = FALSE;
4243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (firsttime) {
4253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         debug = debug_get_bool_option("SVGA_DUMP_CMD", FALSE);
4263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         skip = debug_get_bool_option("SVGA_SKIP_CMD", FALSE);
4273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
4283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (debug) {
4293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         VMW_FUNC;
4303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         svga_dump_commands(commands, size);
4313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
4323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      firsttime = FALSE;
4333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (skip) {
4343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         size = 0;
4353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
4363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
4373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#endif
4383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   memset(&arg, 0, sizeof(arg));
4403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   memset(&rep, 0, sizeof(rep));
4413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   rep.error = -EFAULT;
443e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   if (pfence)
444e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom      arg.fence_rep = (unsigned long)&rep;
4453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   arg.commands = (unsigned long)commands;
4463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   arg.command_size = size;
447d12f2bb9c03a9e8a08824c849200f5b23c05914cThomas Hellstrom   arg.throttle_us = throttle_us;
448e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   arg.version = vws->ioctl.drm_execbuf_version;
449e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   arg.context_handle = (vws->base.have_vgpu10 ? cid : SVGA3D_INVALID_ID);
450e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul
451e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   /* In DRM_VMW_EXECBUF_VERSION 1, the drm_vmw_execbuf_arg structure ends with
452e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul    * the flags field. The structure size sent to drmCommandWrite must match
453e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul    * the drm_execbuf_version. Otherwise, an invalid value will be returned.
454e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul    */
455e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   argsize = vws->ioctl.drm_execbuf_version > 1 ? sizeof(arg) :
456e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul                offsetof(struct drm_vmw_execbuf_arg, context_handle);
4573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   do {
458e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul       ret = drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_EXECBUF, &arg, argsize);
4593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   } while(ret == -ERESTART);
4603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (ret) {
461c45d22e26a3e66371b239b5aac80170fcbf213f8Brian Paul      vmw_error("%s error %s.\n", __FUNCTION__, strerror(-ret));
462e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul      abort();
4633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
464e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom
4653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (rep.error) {
4663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /*
468e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom       * Kernel has already synced, or caller requested no fence.
4693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
470e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom      if (pfence)
471e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom	 *pfence = NULL;
472e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   } else {
473e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom      if (pfence) {
474fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul         vmw_fences_signal(vws->fence_ops, rep.passed_seqno, rep.seqno,
475fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul                           TRUE);
476e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom
477fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul	 *pfence = vmw_fence_create(vws->fence_ops, rep.handle,
478fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul				    rep.seqno, rep.mask);
479e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom	 if (*pfence == NULL) {
480e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom	    /*
481e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom	     * Fence creation failed. Need to sync.
482e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom	     */
483e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom	    (void) vmw_ioctl_fence_finish(vws, rep.handle, rep.mask);
484e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom	    vmw_ioctl_fence_unref(vws, rep.handle);
485e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom	 }
486e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom      }
4873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
4883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
4893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct vmw_region *
4923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_ioctl_region_create(struct vmw_winsys_screen *vws, uint32_t size)
4933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
4943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct vmw_region *region;
4953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   union drm_vmw_alloc_dmabuf_arg arg;
4963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct drm_vmw_alloc_dmabuf_req *req = &arg.req;
4973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct drm_vmw_dmabuf_rep *rep = &arg.rep;
4983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int ret;
4993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vmw_printf("%s: size = %u\n", __FUNCTION__, size);
5013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   region = CALLOC_STRUCT(vmw_region);
5033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!region)
5043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      goto out_err1;
5053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   memset(&arg, 0, sizeof(arg));
5073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   req->size = size;
5083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   do {
5093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_ALLOC_DMABUF, &arg,
5103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz				sizeof(arg));
5113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   } while (ret == -ERESTART);
5123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (ret) {
514c45d22e26a3e66371b239b5aac80170fcbf213f8Brian Paul      vmw_error("IOCTL failed %d: %s\n", ret, strerror(-ret));
5153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      goto out_err1;
5163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
5173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   region->data = NULL;
5193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   region->handle = rep->handle;
5203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   region->map_handle = rep->map_handle;
5213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   region->map_count = 0;
5223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   region->size = size;
5233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   region->drm_fd = vws->ioctl.drm_fd;
5243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vmw_printf("   gmrId = %u, offset = %u\n",
5263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz              region->ptr.gmrId, region->ptr.offset);
5273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return region;
5293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz out_err1:
531b62a74d3b94024bc08b31394f827761d354d2516Vinson Lee   FREE(region);
5323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return NULL;
5333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
5343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvoid
5363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_ioctl_region_destroy(struct vmw_region *region)
5373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
5383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct drm_vmw_unref_dmabuf_arg arg;
5393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vmw_printf("%s: gmrId = %u, offset = %u\n", __FUNCTION__,
5413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz              region->ptr.gmrId, region->ptr.offset);
5423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (region->data) {
5441284d5b25507a56634519ac385cbc00a00b94417Chia-I Wu      os_munmap(region->data, region->size);
5453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      region->data = NULL;
5463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
5473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   memset(&arg, 0, sizeof(arg));
5493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   arg.handle = region->handle;
5503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   drmCommandWrite(region->drm_fd, DRM_VMW_UNREF_DMABUF, &arg, sizeof(arg));
5513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   FREE(region);
5533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
5543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5553192633d4abe262d413e41feb871fe8deed409d8Jakob BornecrantzSVGAGuestPtr
5563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_ioctl_region_ptr(struct vmw_region *region)
5573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
558fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   SVGAGuestPtr ptr = {region->handle, 0};
559fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   return ptr;
5603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
5613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvoid *
5633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_ioctl_region_map(struct vmw_region *region)
5643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
5653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   void *map;
5663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vmw_printf("%s: gmrId = %u, offset = %u\n", __FUNCTION__,
5683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz              region->ptr.gmrId, region->ptr.offset);
5693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (region->data == NULL) {
5711284d5b25507a56634519ac385cbc00a00b94417Chia-I Wu      map = os_mmap(NULL, region->size, PROT_READ | PROT_WRITE, MAP_SHARED,
5723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz		 region->drm_fd, region->map_handle);
5733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (map == MAP_FAILED) {
574c45d22e26a3e66371b239b5aac80170fcbf213f8Brian Paul	 vmw_error("%s: Map failed.\n", __FUNCTION__);
5753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz	 return NULL;
5763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
5773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      region->data = map;
5793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
5803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   ++region->map_count;
5823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return region->data;
5843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
5853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvoid
5873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_ioctl_region_unmap(struct vmw_region *region)
5883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
5893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vmw_printf("%s: gmrId = %u, offset = %u\n", __FUNCTION__,
5903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz              region->ptr.gmrId, region->ptr.offset);
5913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   --region->map_count;
5923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
5933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
594fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul/**
595fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * vmw_ioctl_syncforcpu - Synchronize a buffer object for CPU usage
596fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul *
597fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @region: Pointer to a struct vmw_region representing the buffer object.
598fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @dont_block: Dont wait for GPU idle, but rather return -EBUSY if the
599fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * GPU is busy with the buffer object.
600fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @readonly: Hint that the CPU access is read-only.
601fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @allow_cs: Allow concurrent command submission while the buffer is
602fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * synchronized for CPU. If FALSE command submissions referencing the
603fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * buffer will block until a corresponding call to vmw_ioctl_releasefromcpu.
604fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul *
605fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * This function idles any GPU activities touching the buffer and blocks
606fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * command submission of commands referencing the buffer, even from
607fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * other processes.
608fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul */
609fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulint
610fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulvmw_ioctl_syncforcpu(struct vmw_region *region,
611fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul                     boolean dont_block,
612fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul                     boolean readonly,
613fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul                     boolean allow_cs)
614fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul{
615fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   struct drm_vmw_synccpu_arg arg;
616fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
617fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   memset(&arg, 0, sizeof(arg));
618fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   arg.op = drm_vmw_synccpu_grab;
619fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   arg.handle = region->handle;
620fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   arg.flags = drm_vmw_synccpu_read;
621fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   if (!readonly)
622fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      arg.flags |= drm_vmw_synccpu_write;
623fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   if (dont_block)
624fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      arg.flags |= drm_vmw_synccpu_dontblock;
625fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   if (allow_cs)
626fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      arg.flags |= drm_vmw_synccpu_allow_cs;
627fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
628fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   return drmCommandWrite(region->drm_fd, DRM_VMW_SYNCCPU, &arg, sizeof(arg));
629fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul}
630fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
631fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul/**
632fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * vmw_ioctl_releasefromcpu - Undo a previous syncforcpu.
633fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul *
634fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @region: Pointer to a struct vmw_region representing the buffer object.
635fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @readonly: Should hold the same value as the matching syncforcpu call.
636fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @allow_cs: Should hold the same value as the matching syncforcpu call.
637fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul */
638fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulvoid
639fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulvmw_ioctl_releasefromcpu(struct vmw_region *region,
640fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul                         boolean readonly,
641fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul                         boolean allow_cs)
642fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul{
643fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   struct drm_vmw_synccpu_arg arg;
644fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
645fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   memset(&arg, 0, sizeof(arg));
646fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   arg.op = drm_vmw_synccpu_release;
647fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   arg.handle = region->handle;
648fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   arg.flags = drm_vmw_synccpu_read;
649fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   if (!readonly)
650fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      arg.flags |= drm_vmw_synccpu_write;
651fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   if (allow_cs)
652fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      arg.flags |= drm_vmw_synccpu_allow_cs;
653fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
654fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   (void) drmCommandWrite(region->drm_fd, DRM_VMW_SYNCCPU, &arg, sizeof(arg));
655fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul}
656fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
657e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstromvoid
658e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstromvmw_ioctl_fence_unref(struct vmw_winsys_screen *vws,
659e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom		      uint32_t handle)
6603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
661e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   struct drm_vmw_fence_arg arg;
662e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   int ret;
6633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
664e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   memset(&arg, 0, sizeof(arg));
665e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   arg.handle = handle;
6663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
667e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   ret = drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_FENCE_UNREF,
668e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom			 &arg, sizeof(arg));
669e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   if (ret != 0)
670c45d22e26a3e66371b239b5aac80170fcbf213f8Brian Paul      vmw_error("%s Failed\n", __FUNCTION__);
671e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom}
6723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
673a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline uint32_t
674e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstromvmw_drm_fence_flags(uint32_t flags)
6753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
676e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom    uint32_t dflags = 0;
6773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
678e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom    if (flags & SVGA_FENCE_FLAG_EXEC)
679e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom	dflags |= DRM_VMW_FENCE_FLAG_EXEC;
680e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom    if (flags & SVGA_FENCE_FLAG_QUERY)
681e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom	dflags |= DRM_VMW_FENCE_FLAG_QUERY;
682e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom
683e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom    return dflags;
684e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom}
6853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
687e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstromint
688e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstromvmw_ioctl_fence_signalled(struct vmw_winsys_screen *vws,
689e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom			  uint32_t handle,
690e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom			  uint32_t flags)
691e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom{
692e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   struct drm_vmw_fence_signaled_arg arg;
693e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   uint32_t vflags = vmw_drm_fence_flags(flags);
694e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   int ret;
6953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   memset(&arg, 0, sizeof(arg));
697e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   arg.handle = handle;
698e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   arg.flags = vflags;
6993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
700e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_FENCE_SIGNALED,
701e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom			     &arg, sizeof(arg));
702e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom
703e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   if (ret != 0)
704e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom      return ret;
705e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom
706fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   vmw_fences_signal(vws->fence_ops, arg.passed_seqno, 0, FALSE);
707fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
708e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   return (arg.signaled) ? 0 : -1;
7093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
7103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
712e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom
7133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzint
7143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_ioctl_fence_finish(struct vmw_winsys_screen *vws,
715e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom                       uint32_t handle,
716e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom		       uint32_t flags)
7173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
718e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   struct drm_vmw_fence_wait_arg arg;
719e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   uint32_t vflags = vmw_drm_fence_flags(flags);
720e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   int ret;
721e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom
722e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   memset(&arg, 0, sizeof(arg));
723e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom
724e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   arg.handle = handle;
725395c7b8fa17069fe996a63a8bca2bfd0fe3f16a0Thomas Hellstrom   arg.timeout_us = VMW_FENCE_TIMEOUT_SECONDS*1000000;
726e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   arg.lazy = 0;
727e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   arg.flags = vflags;
728e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom
729e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_FENCE_WAIT,
730e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom			     &arg, sizeof(arg));
731e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom
732e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   if (ret != 0)
733c45d22e26a3e66371b239b5aac80170fcbf213f8Brian Paul      vmw_error("%s Failed\n", __FUNCTION__);
7343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return 0;
7363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
7373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
738fe6a854477c2ed30c37c200668a4dc86512120f7Brian Pauluint32
739fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulvmw_ioctl_shader_create(struct vmw_winsys_screen *vws,
740fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul			SVGA3dShaderType type,
741fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul			uint32 code_len)
742fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul{
743fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   struct drm_vmw_shader_create_arg sh_arg;
744fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   int ret;
745fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
746fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   VMW_FUNC;
747fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
748fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   memset(&sh_arg, 0, sizeof(sh_arg));
749fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
750fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   sh_arg.size = code_len;
751fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   sh_arg.buffer_handle = SVGA3D_INVALID_ID;
752fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   sh_arg.shader_handle = SVGA3D_INVALID_ID;
753fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   switch (type) {
754fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   case SVGA3D_SHADERTYPE_VS:
755fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      sh_arg.shader_type = drm_vmw_shader_type_vs;
756fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      break;
757fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   case SVGA3D_SHADERTYPE_PS:
758fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      sh_arg.shader_type = drm_vmw_shader_type_ps;
759fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      break;
760fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   default:
761fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      assert(!"Invalid shader type.");
762fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      break;
763fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   }
764fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
765fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_CREATE_SHADER,
766fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul			     &sh_arg, sizeof(sh_arg));
767fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
768fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   if (ret)
769fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      return SVGA3D_INVALID_ID;
770fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
771fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   return sh_arg.shader_handle;
772fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul}
773fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
774fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulvoid
775fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulvmw_ioctl_shader_destroy(struct vmw_winsys_screen *vws, uint32 shid)
776fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul{
777fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   struct drm_vmw_shader_arg sh_arg;
778fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
779fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   VMW_FUNC;
780fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
781fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   memset(&sh_arg, 0, sizeof(sh_arg));
782fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   sh_arg.handle = shid;
783fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
784fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   (void)drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_UNREF_SHADER,
785fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul			 &sh_arg, sizeof(sh_arg));
786fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
787fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul}
788fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
789fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulstatic int
790fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulvmw_ioctl_parse_caps(struct vmw_winsys_screen *vws,
791fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul		     const uint32_t *cap_buffer)
792fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul{
793fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   int i;
794fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
795fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   if (vws->base.have_gb_objects) {
796fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      for (i = 0; i < vws->ioctl.num_cap_3d; ++i) {
797fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul	 vws->ioctl.cap_3d[i].has_cap = TRUE;
798fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul	 vws->ioctl.cap_3d[i].result.u = cap_buffer[i];
799fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      }
800fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      return 0;
801fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   } else {
802fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      const uint32 *capsBlock;
803fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      const SVGA3dCapsRecord *capsRecord = NULL;
804fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      uint32 offset;
805fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      const SVGA3dCapPair *capArray;
806fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      int numCaps, index;
807fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
808fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      /*
809fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul       * Search linearly through the caps block records for the specified type.
810fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul       */
811fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      capsBlock = cap_buffer;
812fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      for (offset = 0; capsBlock[offset] != 0; offset += capsBlock[offset]) {
813fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul	 const SVGA3dCapsRecord *record;
814fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul	 assert(offset < SVGA_FIFO_3D_CAPS_SIZE);
815fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul	 record = (const SVGA3dCapsRecord *) (capsBlock + offset);
816fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul	 if ((record->header.type >= SVGA3DCAPS_RECORD_DEVCAPS_MIN) &&
817fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul	     (record->header.type <= SVGA3DCAPS_RECORD_DEVCAPS_MAX) &&
818fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul	     (!capsRecord || (record->header.type > capsRecord->header.type))) {
819fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul	    capsRecord = record;
820fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul	 }
821fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      }
822fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
823fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      if(!capsRecord)
824fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul	 return -1;
825fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
826fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      /*
827fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul       * Calculate the number of caps from the size of the record.
828fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul       */
829fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      capArray = (const SVGA3dCapPair *) capsRecord->data;
830fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      numCaps = (int) ((capsRecord->header.length * sizeof(uint32) -
831fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul			sizeof capsRecord->header) / (2 * sizeof(uint32)));
832fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
833fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      for (i = 0; i < numCaps; i++) {
834fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul	 index = capArray[i][0];
835fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul	 if (index < vws->ioctl.num_cap_3d) {
836fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul	    vws->ioctl.cap_3d[index].has_cap = TRUE;
837fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul	    vws->ioctl.cap_3d[index].result.u = capArray[i][1];
838fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul	 } else {
839fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul	    debug_printf("Unknown devcaps seen: %d\n", index);
840fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul	 }
841fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      }
842fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   }
843fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   return 0;
844fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul}
8453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzboolean
8473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_ioctl_init(struct vmw_winsys_screen *vws)
8483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
8493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct drm_vmw_getparam_arg gp_arg;
850e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   struct drm_vmw_get_3d_cap_arg cap_arg;
851e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   unsigned int size;
8523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int ret;
853fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   uint32_t *cap_buffer;
854fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   drmVersionPtr version;
855e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   boolean drm_gb_capable;
856f5e681f3fae6b95b76bb068b367f5f96c58073c8Thomas Hellstrom   boolean have_drm_2_5;
8573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   VMW_FUNC;
8593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
860fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   version = drmGetVersion(vws->ioctl.drm_fd);
861fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   if (!version)
862fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      goto out_no_version;
863fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
864f5e681f3fae6b95b76bb068b367f5f96c58073c8Thomas Hellstrom   have_drm_2_5 = version->version_major > 2 ||
865fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      (version->version_major == 2 && version->version_minor > 4);
8662f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom   vws->ioctl.have_drm_2_6 = version->version_major > 2 ||
8672f6fcd65f2401695427bcbf1f2bd428d466ecda0Thomas Hellstrom      (version->version_major == 2 && version->version_minor > 5);
868e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   vws->ioctl.have_drm_2_9 = version->version_major > 2 ||
869e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul      (version->version_major == 2 && version->version_minor > 8);
870e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul
871e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   vws->ioctl.drm_execbuf_version = vws->ioctl.have_drm_2_9 ? 2 : 1;
872e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul
873e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   drm_gb_capable = have_drm_2_5;
874fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
8753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   memset(&gp_arg, 0, sizeof(gp_arg));
87649e4b624e5f4a68d51eb9681dbd2218aea0645faJakob Bornecrantz   gp_arg.param = DRM_VMW_PARAM_3D;
87749e4b624e5f4a68d51eb9681dbd2218aea0645faJakob Bornecrantz   ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
87849e4b624e5f4a68d51eb9681dbd2218aea0645faJakob Bornecrantz			     &gp_arg, sizeof(gp_arg));
87949e4b624e5f4a68d51eb9681dbd2218aea0645faJakob Bornecrantz   if (ret || gp_arg.value == 0) {
880c45d22e26a3e66371b239b5aac80170fcbf213f8Brian Paul      vmw_error("No 3D enabled (%i, %s).\n", ret, strerror(-ret));
881e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom      goto out_no_3d;
88249e4b624e5f4a68d51eb9681dbd2218aea0645faJakob Bornecrantz   }
88349e4b624e5f4a68d51eb9681dbd2218aea0645faJakob Bornecrantz
88449e4b624e5f4a68d51eb9681dbd2218aea0645faJakob Bornecrantz   memset(&gp_arg, 0, sizeof(gp_arg));
885e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   gp_arg.param = DRM_VMW_PARAM_FIFO_HW_VERSION;
8863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
8873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz			     &gp_arg, sizeof(gp_arg));
8883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (ret) {
889c45d22e26a3e66371b239b5aac80170fcbf213f8Brian Paul      vmw_error("Failed to get fifo hw version (%i, %s).\n",
890c45d22e26a3e66371b239b5aac80170fcbf213f8Brian Paul                ret, strerror(-ret));
891e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom      goto out_no_3d;
892e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   }
893e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   vws->ioctl.hwversion = gp_arg.value;
894e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom
895fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   memset(&gp_arg, 0, sizeof(gp_arg));
896fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   gp_arg.param = DRM_VMW_PARAM_HW_CAPS;
897fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
898fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul                             &gp_arg, sizeof(gp_arg));
899fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   if (ret)
900fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      vws->base.have_gb_objects = FALSE;
901fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   else
902fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      vws->base.have_gb_objects =
903fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul         !!(gp_arg.value & (uint64_t) SVGA_CAP_GBOBJECTS);
904fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
905e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   if (vws->base.have_gb_objects && !drm_gb_capable)
906fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      goto out_no_3d;
907fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
908e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   vws->base.have_vgpu10 = FALSE;
909fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   if (vws->base.have_gb_objects) {
910fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      memset(&gp_arg, 0, sizeof(gp_arg));
911fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      gp_arg.param = DRM_VMW_PARAM_3D_CAPS_SIZE;
912fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
913fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul                                &gp_arg, sizeof(gp_arg));
914fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      if (ret)
915fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul         size = SVGA_FIFO_3D_CAPS_SIZE * sizeof(uint32_t);
916fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      else
917fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul         size = gp_arg.value;
918fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
919fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      if (vws->base.have_gb_objects)
920fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul         vws->ioctl.num_cap_3d = size / sizeof(uint32_t);
921fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      else
922fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul         vws->ioctl.num_cap_3d = SVGA3D_DEVCAP_MAX;
923fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
924fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
925fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      memset(&gp_arg, 0, sizeof(gp_arg));
926fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      gp_arg.param = DRM_VMW_PARAM_MAX_MOB_MEMORY;
927fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
928fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul                                &gp_arg, sizeof(gp_arg));
929fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      if (ret) {
930fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul         /* Just guess a large enough value. */
931fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul         vws->ioctl.max_mob_memory = 256*1024*1024;
932fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      } else {
933fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul         vws->ioctl.max_mob_memory = gp_arg.value;
934fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      }
9350c065270c0ff063edba03516b22d734023cac912Charmaine Lee
9360c065270c0ff063edba03516b22d734023cac912Charmaine Lee      memset(&gp_arg, 0, sizeof(gp_arg));
9370c065270c0ff063edba03516b22d734023cac912Charmaine Lee      gp_arg.param = DRM_VMW_PARAM_MAX_MOB_SIZE;
9380c065270c0ff063edba03516b22d734023cac912Charmaine Lee      ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
9390c065270c0ff063edba03516b22d734023cac912Charmaine Lee                                &gp_arg, sizeof(gp_arg));
9400c065270c0ff063edba03516b22d734023cac912Charmaine Lee
9410c065270c0ff063edba03516b22d734023cac912Charmaine Lee      if (ret || gp_arg.value == 0) {
9420c065270c0ff063edba03516b22d734023cac912Charmaine Lee           vws->ioctl.max_texture_size = VMW_MAX_DEFAULT_TEXTURE_SIZE;
9430c065270c0ff063edba03516b22d734023cac912Charmaine Lee      } else {
9440c065270c0ff063edba03516b22d734023cac912Charmaine Lee           vws->ioctl.max_texture_size = gp_arg.value;
9450c065270c0ff063edba03516b22d734023cac912Charmaine Lee      }
9460c065270c0ff063edba03516b22d734023cac912Charmaine Lee
947fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      /* Never early flush surfaces, mobs do accounting. */
948fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      vws->ioctl.max_surface_memory = -1;
949e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul
950e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul      if (vws->ioctl.have_drm_2_9) {
951e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul
952e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul         memset(&gp_arg, 0, sizeof(gp_arg));
953e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul         gp_arg.param = DRM_VMW_PARAM_VGPU10;
954e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul         ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
955e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul                                   &gp_arg, sizeof(gp_arg));
956e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul         if (ret == 0 && gp_arg.value != 0) {
957e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul            const char *vgpu10_val;
958e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul
959e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul            debug_printf("Have VGPU10 interface and hardware.\n");
960e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul            vws->base.have_vgpu10 = TRUE;
961e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul            vgpu10_val = getenv("SVGA_VGPU10");
962e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul            if (vgpu10_val && strcmp(vgpu10_val, "0") == 0) {
963e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul               debug_printf("Disabling VGPU10 interface.\n");
964e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul               vws->base.have_vgpu10 = FALSE;
965e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul            } else {
966e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul               debug_printf("Enabling VGPU10 interface.\n");
967e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul            }
968e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul         }
969e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul      }
970fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   } else {
971fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      vws->ioctl.num_cap_3d = SVGA3D_DEVCAP_MAX;
972fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
973fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      memset(&gp_arg, 0, sizeof(gp_arg));
974fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      gp_arg.param = DRM_VMW_PARAM_MAX_SURF_MEMORY;
975f5e681f3fae6b95b76bb068b367f5f96c58073c8Thomas Hellstrom      if (have_drm_2_5)
976f5e681f3fae6b95b76bb068b367f5f96c58073c8Thomas Hellstrom         ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
977f5e681f3fae6b95b76bb068b367f5f96c58073c8Thomas Hellstrom                                   &gp_arg, sizeof(gp_arg));
978f5e681f3fae6b95b76bb068b367f5f96c58073c8Thomas Hellstrom      if (!have_drm_2_5 || ret) {
979fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul         /* Just guess a large enough value, around 800mb. */
980f5e681f3fae6b95b76bb068b367f5f96c58073c8Thomas Hellstrom         vws->ioctl.max_surface_memory = 0x30000000;
981fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      } else {
982fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul         vws->ioctl.max_surface_memory = gp_arg.value;
983fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      }
9840c065270c0ff063edba03516b22d734023cac912Charmaine Lee
9850c065270c0ff063edba03516b22d734023cac912Charmaine Lee      vws->ioctl.max_texture_size = VMW_MAX_DEFAULT_TEXTURE_SIZE;
9860c065270c0ff063edba03516b22d734023cac912Charmaine Lee
987fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      size = SVGA_FIFO_3D_CAPS_SIZE * sizeof(uint32_t);
988fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   }
989fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
990e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul   debug_printf("VGPU10 interface is %s.\n",
991e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul                vws->base.have_vgpu10 ? "on" : "off");
992e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul
993fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   cap_buffer = calloc(1, size);
994fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   if (!cap_buffer) {
995e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom      debug_printf("Failed alloc fifo 3D caps buffer.\n");
996e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom      goto out_no_3d;
9973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
9983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
999fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   vws->ioctl.cap_3d = calloc(vws->ioctl.num_cap_3d,
1000fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul			      sizeof(*vws->ioctl.cap_3d));
1001fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   if (!vws->ioctl.cap_3d) {
1002fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      debug_printf("Failed alloc fifo 3D caps buffer.\n");
1003fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      goto out_no_caparray;
1004fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   }
1005fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul
1006e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   memset(&cap_arg, 0, sizeof(cap_arg));
1007fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   cap_arg.buffer = (uint64_t) (unsigned long) (cap_buffer);
1008e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   cap_arg.max_size = size;
10093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1010e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   ret = drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_GET_3D_CAP,
1011e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom			 &cap_arg, sizeof(cap_arg));
1012e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom
1013e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   if (ret) {
1014e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom      debug_printf("Failed to get 3D capabilities"
1015e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom		   " (%i, %s).\n", ret, strerror(-ret));
1016e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom      goto out_no_caps;
1017e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   }
10183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1019fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   ret = vmw_ioctl_parse_caps(vws, cap_buffer);
1020fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   if (ret) {
1021fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      debug_printf("Failed to parse 3D capabilities"
1022fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul		   " (%i, %s).\n", ret, strerror(-ret));
1023fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul      goto out_no_caps;
1024fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   }
10257988513ac3d86ba367fbe44e73fe483ff96aaa29Neha Bhende
10267988513ac3d86ba367fbe44e73fe483ff96aaa29Neha Bhende   if (((version->version_major == 2 && version->version_minor >= 10)
10277988513ac3d86ba367fbe44e73fe483ff96aaa29Neha Bhende       || version->version_major > 2) && vws->base.have_vgpu10) {
10287988513ac3d86ba367fbe44e73fe483ff96aaa29Neha Bhende
10297988513ac3d86ba367fbe44e73fe483ff96aaa29Neha Bhende     /* support for these commands didn't make it into vmwgfx kernel
10307988513ac3d86ba367fbe44e73fe483ff96aaa29Neha Bhende      * modules before 2.10.
10317988513ac3d86ba367fbe44e73fe483ff96aaa29Neha Bhende      */
10327988513ac3d86ba367fbe44e73fe483ff96aaa29Neha Bhende      vws->base.have_generate_mipmap_cmd = TRUE;
10337988513ac3d86ba367fbe44e73fe483ff96aaa29Neha Bhende      vws->base.have_set_predication_cmd = TRUE;
10347988513ac3d86ba367fbe44e73fe483ff96aaa29Neha Bhende   }
10357988513ac3d86ba367fbe44e73fe483ff96aaa29Neha Bhende
1036fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   free(cap_buffer);
1037fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   drmFreeVersion(version);
10383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vmw_printf("%s OK\n", __FUNCTION__);
10393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
1040e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom  out_no_caps:
1041fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   free(vws->ioctl.cap_3d);
1042fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul  out_no_caparray:
1043fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   free(cap_buffer);
1044e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom  out_no_3d:
1045fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   drmFreeVersion(version);
1046fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul  out_no_version:
1047fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul   vws->ioctl.num_cap_3d = 0;
10483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   debug_printf("%s Failed\n", __FUNCTION__);
10493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return FALSE;
10503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
10513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvoid
10553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_ioctl_cleanup(struct vmw_winsys_screen *vws)
10563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
10573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   VMW_FUNC;
10583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
1059