1 /**********************************************************
2 * Copyright 2009 VMware, Inc. All rights reserved.
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 **********************************************************/
28 * This file implements the SVGA interface into this winsys, defined
29 * in drivers/svga/svga_winsys.h.
31 * @author Keith Whitwell
32 * @author Jose Fonseca
37 #include "svga3d_caps.h"
39 #include "util/u_inlines.h"
40 #include "util/u_math.h"
41 #include "util/u_memory.h"
42 #include "pipebuffer/pb_buffer.h"
43 #include "pipebuffer/pb_bufmgr.h"
44 #include "svga_winsys.h"
45 #include "vmw_context.h"
46 #include "vmw_screen.h"
47 #include "vmw_surface.h"
48 #include "vmw_buffer.h"
49 #include "vmw_fence.h"
52 static struct svga_winsys_buffer
*
53 vmw_svga_winsys_buffer_create(struct svga_winsys_screen
*sws
,
58 struct vmw_winsys_screen
*vws
= vmw_winsys_screen(sws
);
60 struct pb_manager
*provider
;
61 struct pb_buffer
*buffer
;
63 memset(&desc
, 0, sizeof desc
);
64 desc
.alignment
= alignment
;
67 if (usage
== SVGA_BUFFER_USAGE_PINNED
) {
68 if (vws
->pools
.query_fenced
== NULL
&& !vmw_query_pools_init(vws
))
70 provider
= vws
->pools
.query_fenced
;
72 provider
= vws
->pools
.gmr_fenced
;
75 buffer
= provider
->create_buffer(provider
, size
, &desc
);
77 if(!buffer
&& provider
== vws
->pools
.gmr_fenced
) {
80 provider
= vws
->pools
.gmr_slab_fenced
;
81 buffer
= provider
->create_buffer(provider
, size
, &desc
);
87 return vmw_svga_winsys_buffer(buffer
);
92 vmw_svga_winsys_buffer_map(struct svga_winsys_screen
*sws
,
93 struct svga_winsys_buffer
*buf
,
97 return pb_map(vmw_pb_buffer(buf
), flags
, NULL
);
102 vmw_svga_winsys_buffer_unmap(struct svga_winsys_screen
*sws
,
103 struct svga_winsys_buffer
*buf
)
106 pb_unmap(vmw_pb_buffer(buf
));
111 vmw_svga_winsys_buffer_destroy(struct svga_winsys_screen
*sws
,
112 struct svga_winsys_buffer
*buf
)
114 struct pb_buffer
*pbuf
= vmw_pb_buffer(buf
);
116 pb_reference(&pbuf
, NULL
);
121 vmw_svga_winsys_fence_reference(struct svga_winsys_screen
*sws
,
122 struct pipe_fence_handle
**pdst
,
123 struct pipe_fence_handle
*src
)
125 struct vmw_winsys_screen
*vws
= vmw_winsys_screen(sws
);
127 vmw_fence_reference(vws
, pdst
, src
);
132 vmw_svga_winsys_fence_signalled(struct svga_winsys_screen
*sws
,
133 struct pipe_fence_handle
*fence
,
136 struct vmw_winsys_screen
*vws
= vmw_winsys_screen(sws
);
138 return vmw_fence_signalled(vws
, fence
, flag
);
143 vmw_svga_winsys_fence_finish(struct svga_winsys_screen
*sws
,
144 struct pipe_fence_handle
*fence
,
147 struct vmw_winsys_screen
*vws
= vmw_winsys_screen(sws
);
149 return vmw_fence_finish(vws
, fence
, flag
);
154 static struct svga_winsys_surface
*
155 vmw_svga_winsys_surface_create(struct svga_winsys_screen
*sws
,
156 SVGA3dSurfaceFlags flags
,
157 SVGA3dSurfaceFormat format
,
162 struct vmw_winsys_screen
*vws
= vmw_winsys_screen(sws
);
163 struct vmw_svga_winsys_surface
*surface
;
165 surface
= CALLOC_STRUCT(vmw_svga_winsys_surface
);
169 pipe_reference_init(&surface
->refcnt
, 1);
170 p_atomic_set(&surface
->validated
, 0);
171 surface
->screen
= vws
;
172 surface
->sid
= vmw_ioctl_surface_create(vws
,
174 numFaces
, numMipLevels
);
175 if(surface
->sid
== SVGA3D_INVALID_ID
)
178 return svga_winsys_surface(surface
);
188 vmw_svga_winsys_surface_is_flushed(struct svga_winsys_screen
*sws
,
189 struct svga_winsys_surface
*surface
)
191 struct vmw_svga_winsys_surface
*vsurf
= vmw_svga_winsys_surface(surface
);
192 return (p_atomic_read(&vsurf
->validated
) == 0);
197 vmw_svga_winsys_surface_ref(struct svga_winsys_screen
*sws
,
198 struct svga_winsys_surface
**pDst
,
199 struct svga_winsys_surface
*src
)
201 struct vmw_svga_winsys_surface
*d_vsurf
= vmw_svga_winsys_surface(*pDst
);
202 struct vmw_svga_winsys_surface
*s_vsurf
= vmw_svga_winsys_surface(src
);
204 vmw_svga_winsys_surface_reference(&d_vsurf
, s_vsurf
);
205 *pDst
= svga_winsys_surface(d_vsurf
);
210 vmw_svga_winsys_destroy(struct svga_winsys_screen
*sws
)
212 struct vmw_winsys_screen
*vws
= vmw_winsys_screen(sws
);
214 vmw_winsys_destroy(vws
);
218 static SVGA3dHardwareVersion
219 vmw_svga_winsys_get_hw_version(struct svga_winsys_screen
*sws
)
221 struct vmw_winsys_screen
*vws
= vmw_winsys_screen(sws
);
223 return (SVGA3dHardwareVersion
) vws
->ioctl
.hwversion
;
228 vmw_svga_winsys_get_cap(struct svga_winsys_screen
*sws
,
229 SVGA3dDevCapIndex index
,
230 SVGA3dDevCapResult
*result
)
232 struct vmw_winsys_screen
*vws
= vmw_winsys_screen(sws
);
233 const uint32
*capsBlock
;
234 const SVGA3dCapsRecord
*capsRecord
= NULL
;
236 const SVGA3dCapPair
*capArray
;
237 int numCaps
, first
, last
;
239 if(vws
->ioctl
.hwversion
< SVGA3D_HWVERSION_WS6_B1
)
243 * Search linearly through the caps block records for the specified type.
245 capsBlock
= (const uint32
*)vws
->ioctl
.buffer
;
246 for (offset
= 0; capsBlock
[offset
] != 0; offset
+= capsBlock
[offset
]) {
247 const SVGA3dCapsRecord
*record
;
248 assert(offset
< SVGA_FIFO_3D_CAPS_SIZE
);
249 record
= (const SVGA3dCapsRecord
*) (capsBlock
+ offset
);
250 if ((record
->header
.type
>= SVGA3DCAPS_RECORD_DEVCAPS_MIN
) &&
251 (record
->header
.type
<= SVGA3DCAPS_RECORD_DEVCAPS_MAX
) &&
252 (!capsRecord
|| (record
->header
.type
> capsRecord
->header
.type
))) {
261 * Calculate the number of caps from the size of the record.
263 capArray
= (const SVGA3dCapPair
*) capsRecord
->data
;
264 numCaps
= (int) ((capsRecord
->header
.length
* sizeof(uint32
) -
265 sizeof capsRecord
->header
) / (2 * sizeof(uint32
)));
268 * Binary-search for the cap with the specified index.
270 for (first
= 0, last
= numCaps
- 1; first
<= last
; ) {
271 int mid
= (first
+ last
) / 2;
273 if ((SVGA3dDevCapIndex
) capArray
[mid
][0] == index
) {
277 result
->u
= capArray
[mid
][1];
282 * Divide and conquer.
284 if ((SVGA3dDevCapIndex
) capArray
[mid
][0] > index
) {
296 vmw_winsys_screen_init_svga(struct vmw_winsys_screen
*vws
)
298 vws
->base
.destroy
= vmw_svga_winsys_destroy
;
299 vws
->base
.get_hw_version
= vmw_svga_winsys_get_hw_version
;
300 vws
->base
.get_cap
= vmw_svga_winsys_get_cap
;
301 vws
->base
.context_create
= vmw_svga_winsys_context_create
;
302 vws
->base
.surface_create
= vmw_svga_winsys_surface_create
;
303 vws
->base
.surface_is_flushed
= vmw_svga_winsys_surface_is_flushed
;
304 vws
->base
.surface_reference
= vmw_svga_winsys_surface_ref
;
305 vws
->base
.buffer_create
= vmw_svga_winsys_buffer_create
;
306 vws
->base
.buffer_map
= vmw_svga_winsys_buffer_map
;
307 vws
->base
.buffer_unmap
= vmw_svga_winsys_buffer_unmap
;
308 vws
->base
.buffer_destroy
= vmw_svga_winsys_buffer_destroy
;
309 vws
->base
.fence_reference
= vmw_svga_winsys_fence_reference
;
310 vws
->base
.fence_signalled
= vmw_svga_winsys_fence_signalled
;
311 vws
->base
.fence_finish
= vmw_svga_winsys_fence_finish
;