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 * SVGA buffer manager for Guest Memory Regions (GMRs).
30 * GMRs are used for pixel and vertex data upload/download to/from the virtual
31 * SVGA hardware. There is a limited number of GMRs available, and
32 * creating/destroying them is also a slow operation so we must suballocate
35 * This file implements a pipebuffer library's buffer manager, so that we can
36 * use pipepbuffer's suballocation, fencing, and debugging facilities with GMRs.
38 * @author Jose Fonseca <jfonseca@vmware.com>
44 #include "util/u_inlines.h"
45 #include "util/u_memory.h"
46 #include "pipebuffer/pb_buffer.h"
47 #include "pipebuffer/pb_bufmgr.h"
49 #include "svga_winsys.h"
51 #include "vmw_screen.h"
52 #include "vmw_buffer.h"
55 struct vmw_gmr_bufmgr
;
60 struct pb_buffer base
;
62 struct vmw_gmr_bufmgr
*mgr
;
64 struct vmw_region
*region
;
68 struct pipe_fence_handle
*last_fence
;
73 extern const struct pb_vtbl vmw_gmr_buffer_vtbl
;
76 static INLINE
struct vmw_gmr_buffer
*
77 vmw_gmr_buffer(struct pb_buffer
*buf
)
80 assert(buf
->vtbl
== &vmw_gmr_buffer_vtbl
);
81 return (struct vmw_gmr_buffer
*)buf
;
87 struct pb_manager base
;
89 struct vmw_winsys_screen
*vws
;
93 static INLINE
struct vmw_gmr_bufmgr
*
94 vmw_gmr_bufmgr(struct pb_manager
*mgr
)
97 return (struct vmw_gmr_bufmgr
*)mgr
;
102 vmw_gmr_buffer_destroy(struct pb_buffer
*_buf
)
104 struct vmw_gmr_buffer
*buf
= vmw_gmr_buffer(_buf
);
107 if(buf
->last_fence
) {
108 struct svga_winsys_screen
*sws
= &buf
->mgr
->vws
->base
;
109 assert(sws
->fence_signalled(sws
, buf
->last_fence
, 0) == 0);
113 vmw_ioctl_region_unmap(buf
->region
);
115 vmw_ioctl_region_destroy(buf
->region
);
122 vmw_gmr_buffer_map(struct pb_buffer
*_buf
,
125 struct vmw_gmr_buffer
*buf
= vmw_gmr_buffer(_buf
);
131 vmw_gmr_buffer_unmap(struct pb_buffer
*_buf
)
139 vmw_gmr_buffer_get_base_buffer(struct pb_buffer
*buf
,
140 struct pb_buffer
**base_buf
,
148 static enum pipe_error
149 vmw_gmr_buffer_validate( struct pb_buffer
*_buf
,
150 struct pb_validate
*vl
,
159 vmw_gmr_buffer_fence( struct pb_buffer
*_buf
,
160 struct pipe_fence_handle
*fence
)
162 /* We don't need to do anything, as the pipebuffer library
163 * will take care of delaying the destruction of fenced buffers */
165 struct vmw_gmr_buffer
*buf
= vmw_gmr_buffer(_buf
);
167 buf
->last_fence
= fence
;
172 const struct pb_vtbl vmw_gmr_buffer_vtbl
= {
173 vmw_gmr_buffer_destroy
,
175 vmw_gmr_buffer_unmap
,
176 vmw_gmr_buffer_validate
,
177 vmw_gmr_buffer_fence
,
178 vmw_gmr_buffer_get_base_buffer
182 static struct pb_buffer
*
183 vmw_gmr_bufmgr_create_buffer(struct pb_manager
*_mgr
,
185 const struct pb_desc
*desc
)
187 struct vmw_gmr_bufmgr
*mgr
= vmw_gmr_bufmgr(_mgr
);
188 struct vmw_winsys_screen
*vws
= mgr
->vws
;
189 struct vmw_gmr_buffer
*buf
;
191 buf
= CALLOC_STRUCT(vmw_gmr_buffer
);
195 pipe_reference_init(&buf
->base
.base
.reference
, 1);
196 buf
->base
.base
.alignment
= desc
->alignment
;
197 buf
->base
.base
.usage
= desc
->usage
;
198 buf
->base
.base
.size
= size
;
199 buf
->base
.vtbl
= &vmw_gmr_buffer_vtbl
;
202 buf
->region
= vmw_ioctl_region_create(vws
, size
);
206 buf
->map
= vmw_ioctl_region_map(buf
->region
);
213 vmw_ioctl_region_destroy(buf
->region
);
222 vmw_gmr_bufmgr_flush(struct pb_manager
*mgr
)
229 vmw_gmr_bufmgr_destroy(struct pb_manager
*_mgr
)
231 struct vmw_gmr_bufmgr
*mgr
= vmw_gmr_bufmgr(_mgr
);
237 vmw_gmr_bufmgr_create(struct vmw_winsys_screen
*vws
)
239 struct vmw_gmr_bufmgr
*mgr
;
241 mgr
= CALLOC_STRUCT(vmw_gmr_bufmgr
);
245 mgr
->base
.destroy
= vmw_gmr_bufmgr_destroy
;
246 mgr
->base
.create_buffer
= vmw_gmr_bufmgr_create_buffer
;
247 mgr
->base
.flush
= vmw_gmr_bufmgr_flush
;
256 vmw_gmr_bufmgr_region_ptr(struct pb_buffer
*buf
,
257 struct SVGAGuestPtr
*ptr
)
259 struct pb_buffer
*base_buf
;
261 struct vmw_gmr_buffer
*gmr_buf
;
263 pb_get_base_buffer( buf
, &base_buf
, &offset
);
265 gmr_buf
= vmw_gmr_buffer(base_buf
);
269 *ptr
= vmw_ioctl_region_ptr(gmr_buf
->region
);
271 ptr
->offset
+= offset
;