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
)
43 struct vmw_svga_winsys_surface
*vsrf
= vmw_svga_winsys_surface(srf
);
45 struct pb_buffer
*pb_buf
;
47 struct vmw_winsys_screen
*vws
= vsrf
->screen
;
50 assert((flags
& (PIPE_TRANSFER_READ
| PIPE_TRANSFER_WRITE
)) != 0);
51 pipe_mutex_lock(vsrf
->mutex
);
55 * Only allow multiple readers to map.
57 if ((flags
& PIPE_TRANSFER_WRITE
) ||
58 (vsrf
->map_mode
& PIPE_TRANSFER_WRITE
))
68 * If we intend to read, there's no point discarding the
71 if (flags
& PIPE_TRANSFER_READ
|| vsrf
->shared
)
72 flags
&= ~PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
;
75 * Discard is a hint to a synchronized map.
77 if (flags
& PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
)
78 flags
&= ~PIPE_TRANSFER_UNSYNCHRONIZED
;
81 * The surface is allowed to be referenced on the command stream iff
82 * we're mapping unsynchronized or discard. This is an early check.
83 * We need to recheck after a failing discard map.
85 if (!(flags
& (PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
|
86 PIPE_TRANSFER_UNSYNCHRONIZED
)) &&
87 p_atomic_read(&vsrf
->validated
)) {
92 pb_flags
= flags
& (PIPE_TRANSFER_READ_WRITE
| PIPE_TRANSFER_UNSYNCHRONIZED
);
94 if (flags
& PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
) {
95 struct pb_manager
*provider
;
99 * First, if possible, try to map existing storage with DONTBLOCK.
101 if (!p_atomic_read(&vsrf
->validated
)) {
102 data
= vmw_svga_winsys_buffer_map(&vws
->base
, vsrf
->buf
,
103 PIPE_TRANSFER_DONTBLOCK
| pb_flags
);
109 * Attempt to get a new buffer.
111 provider
= vws
->pools
.mob_fenced
;
112 memset(&desc
, 0, sizeof(desc
));
113 desc
.alignment
= 4096;
114 pb_buf
= provider
->create_buffer(provider
, vsrf
->size
, &desc
);
115 if (pb_buf
!= NULL
) {
116 struct svga_winsys_buffer
*vbuf
=
117 vmw_svga_winsys_buffer_wrap(pb_buf
);
119 data
= vmw_svga_winsys_buffer_map(&vws
->base
, vbuf
, pb_flags
);
123 * We've discarded data on this surface and thus
124 * it's data is no longer consider referenced.
126 vmw_swc_surface_clear_reference(swc
, vsrf
);
128 vmw_svga_winsys_buffer_destroy(&vws
->base
, vsrf
->buf
);
132 vmw_svga_winsys_buffer_destroy(&vws
->base
, vbuf
);
135 * We couldn't get and map a new buffer for some reason.
136 * Fall through to an ordinary map.
137 * But tell pipe driver to flush now if already on validate list,
138 * Otherwise we'll overwrite previous contents.
140 if (!(flags
& PIPE_TRANSFER_UNSYNCHRONIZED
) &&
141 p_atomic_read(&vsrf
->validated
)) {
147 pb_flags
|= (flags
& PIPE_TRANSFER_DONTBLOCK
);
148 data
= vmw_svga_winsys_buffer_map(&vws
->base
, vsrf
->buf
, pb_flags
);
155 vsrf
->map_mode
= flags
& (PIPE_TRANSFER_READ
| PIPE_TRANSFER_WRITE
);
157 pipe_mutex_unlock(vsrf
->mutex
);
163 vmw_svga_winsys_surface_unmap(struct svga_winsys_context
*swc
,
164 struct svga_winsys_surface
*srf
,
167 struct vmw_svga_winsys_surface
*vsrf
= vmw_svga_winsys_surface(srf
);
168 pipe_mutex_lock(vsrf
->mutex
);
169 if (--vsrf
->mapcount
== 0) {
170 *rebind
= vsrf
->rebind
;
171 vsrf
->rebind
= FALSE
;
172 vmw_svga_winsys_buffer_unmap(&vsrf
->screen
->base
, vsrf
->buf
);
176 pipe_mutex_unlock(vsrf
->mutex
);
180 vmw_svga_winsys_surface_reference(struct vmw_svga_winsys_surface
**pdst
,
181 struct vmw_svga_winsys_surface
*src
)
183 struct pipe_reference
*src_ref
;
184 struct pipe_reference
*dst_ref
;
185 struct vmw_svga_winsys_surface
*dst
;
187 if(pdst
== NULL
|| *pdst
== src
)
192 src_ref
= src
? &src
->refcnt
: NULL
;
193 dst_ref
= dst
? &dst
->refcnt
: NULL
;
195 if (pipe_reference(dst_ref
, src_ref
)) {
197 vmw_svga_winsys_buffer_destroy(&dst
->screen
->base
, dst
->buf
);
198 vmw_ioctl_surface_destroy(dst
->screen
, dst
->sid
);
200 /* to detect dangling pointers */
201 assert(p_atomic_read(&dst
->validated
) == 0);
202 dst
->sid
= SVGA3D_INVALID_ID
;
204 pipe_mutex_destroy(dst
->mutex
);