1 /**********************************************************
2 * Copyright 2009-2015 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 #include "util/u_debug.h"
29 #include "util/u_memory.h"
30 #include "pipe/p_defines.h"
31 #include "vmw_surface.h"
32 #include "vmw_screen.h"
33 #include "vmw_buffer.h"
34 #include "vmw_context.h"
35 #include "pipebuffer/pb_bufmgr.h"
39 vmw_svga_winsys_surface_map(struct svga_winsys_context
*swc
,
40 struct svga_winsys_surface
*srf
,
41 unsigned flags
, boolean
*retry
,
44 struct vmw_svga_winsys_surface
*vsrf
= vmw_svga_winsys_surface(srf
);
46 struct pb_buffer
*pb_buf
;
48 struct vmw_winsys_screen
*vws
= vsrf
->screen
;
52 assert((flags
& (PIPE_TRANSFER_READ
| PIPE_TRANSFER_WRITE
)) != 0);
53 mtx_lock(&vsrf
->mutex
);
56 /* Other mappers will get confused if we discard. */
57 flags
&= ~PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
;
63 * If we intend to read, there's no point discarding the
66 if (flags
& PIPE_TRANSFER_READ
|| vsrf
->shared
)
67 flags
&= ~PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
;
70 * Discard is a hint to a synchronized map.
72 if (flags
& PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
)
73 flags
&= ~PIPE_TRANSFER_UNSYNCHRONIZED
;
76 * The surface is allowed to be referenced on the command stream iff
77 * we're mapping unsynchronized or discard. This is an early check.
78 * We need to recheck after a failing discard map.
80 if (!(flags
& (PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
|
81 PIPE_TRANSFER_UNSYNCHRONIZED
)) &&
82 p_atomic_read(&vsrf
->validated
)) {
87 pb_flags
= flags
& (PIPE_TRANSFER_READ_WRITE
| PIPE_TRANSFER_UNSYNCHRONIZED
|
88 PIPE_TRANSFER_PERSISTENT
);
90 if (flags
& PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
) {
91 struct pb_manager
*provider
;
95 * First, if possible, try to map existing storage with DONTBLOCK.
97 if (!p_atomic_read(&vsrf
->validated
)) {
98 data
= vmw_svga_winsys_buffer_map(&vws
->base
, vsrf
->buf
,
99 PIPE_TRANSFER_DONTBLOCK
| pb_flags
);
105 * Attempt to get a new buffer.
107 provider
= vws
->pools
.mob_fenced
;
108 memset(&desc
, 0, sizeof(desc
));
109 desc
.alignment
= 4096;
110 pb_buf
= provider
->create_buffer(provider
, vsrf
->size
, &desc
);
111 if (pb_buf
!= NULL
) {
112 struct svga_winsys_buffer
*vbuf
=
113 vmw_svga_winsys_buffer_wrap(pb_buf
);
115 data
= vmw_svga_winsys_buffer_map(&vws
->base
, vbuf
, pb_flags
);
119 * We've discarded data on this surface and thus
120 * it's data is no longer consider referenced.
122 vmw_swc_surface_clear_reference(swc
, vsrf
);
124 vmw_svga_winsys_buffer_destroy(&vws
->base
, vsrf
->buf
);
127 /* Rebind persistent maps immediately */
128 if (flags
& PIPE_TRANSFER_PERSISTENT
) {
130 vsrf
->rebind
= FALSE
;
134 vmw_svga_winsys_buffer_destroy(&vws
->base
, vbuf
);
137 * We couldn't get and map a new buffer for some reason.
138 * Fall through to an ordinary map.
139 * But tell pipe driver to flush now if already on validate list,
140 * Otherwise we'll overwrite previous contents.
142 if (!(flags
& PIPE_TRANSFER_UNSYNCHRONIZED
) &&
143 p_atomic_read(&vsrf
->validated
)) {
149 pb_flags
|= (flags
& PIPE_TRANSFER_DONTBLOCK
);
150 data
= vmw_svga_winsys_buffer_map(&vws
->base
, vsrf
->buf
, pb_flags
);
157 vsrf
->map_mode
= flags
& (PIPE_TRANSFER_READ
| PIPE_TRANSFER_WRITE
);
159 mtx_unlock(&vsrf
->mutex
);
165 vmw_svga_winsys_surface_unmap(struct svga_winsys_context
*swc
,
166 struct svga_winsys_surface
*srf
,
169 struct vmw_svga_winsys_surface
*vsrf
= vmw_svga_winsys_surface(srf
);
170 mtx_lock(&vsrf
->mutex
);
171 if (--vsrf
->mapcount
== 0) {
172 *rebind
= vsrf
->rebind
;
173 vsrf
->rebind
= FALSE
;
177 vmw_svga_winsys_buffer_unmap(&vsrf
->screen
->base
, vsrf
->buf
);
178 mtx_unlock(&vsrf
->mutex
);
182 vmw_svga_winsys_surface_reference(struct vmw_svga_winsys_surface
**pdst
,
183 struct vmw_svga_winsys_surface
*src
)
185 struct pipe_reference
*src_ref
;
186 struct pipe_reference
*dst_ref
;
187 struct vmw_svga_winsys_surface
*dst
;
189 if(pdst
== NULL
|| *pdst
== src
)
194 src_ref
= src
? &src
->refcnt
: NULL
;
195 dst_ref
= dst
? &dst
->refcnt
: NULL
;
197 if (pipe_reference(dst_ref
, src_ref
)) {
199 vmw_svga_winsys_buffer_destroy(&dst
->screen
->base
, dst
->buf
);
200 vmw_ioctl_surface_destroy(dst
->screen
, dst
->sid
);
202 /* to detect dangling pointers */
203 assert(p_atomic_read(&dst
->validated
) == 0);
204 dst
->sid
= SVGA3D_INVALID_ID
;
206 mtx_destroy(&dst
->mutex
);