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 mtx_lock(&vsrf
->mutex
);
54 /* Other mappers will get confused if we discard. */
55 flags
&= ~PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
;
61 * If we intend to read, there's no point discarding the
64 if (flags
& PIPE_TRANSFER_READ
|| vsrf
->shared
)
65 flags
&= ~PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
;
68 * Discard is a hint to a synchronized map.
70 if (flags
& PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
)
71 flags
&= ~PIPE_TRANSFER_UNSYNCHRONIZED
;
74 * The surface is allowed to be referenced on the command stream iff
75 * we're mapping unsynchronized or discard. This is an early check.
76 * We need to recheck after a failing discard map.
78 if (!(flags
& (PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
|
79 PIPE_TRANSFER_UNSYNCHRONIZED
)) &&
80 p_atomic_read(&vsrf
->validated
)) {
85 pb_flags
= flags
& (PIPE_TRANSFER_READ_WRITE
| PIPE_TRANSFER_UNSYNCHRONIZED
|
86 PIPE_TRANSFER_PERSISTENT
);
88 if (flags
& PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
) {
89 struct pb_manager
*provider
;
93 * First, if possible, try to map existing storage with DONTBLOCK.
95 if (!p_atomic_read(&vsrf
->validated
)) {
96 data
= vmw_svga_winsys_buffer_map(&vws
->base
, vsrf
->buf
,
97 PIPE_TRANSFER_DONTBLOCK
| pb_flags
);
103 * Attempt to get a new buffer.
105 provider
= vws
->pools
.mob_fenced
;
106 memset(&desc
, 0, sizeof(desc
));
107 desc
.alignment
= 4096;
108 pb_buf
= provider
->create_buffer(provider
, vsrf
->size
, &desc
);
109 if (pb_buf
!= NULL
) {
110 struct svga_winsys_buffer
*vbuf
=
111 vmw_svga_winsys_buffer_wrap(pb_buf
);
113 data
= vmw_svga_winsys_buffer_map(&vws
->base
, vbuf
, pb_flags
);
117 * We've discarded data on this surface and thus
118 * it's data is no longer consider referenced.
120 vmw_swc_surface_clear_reference(swc
, vsrf
);
122 vmw_svga_winsys_buffer_destroy(&vws
->base
, vsrf
->buf
);
126 vmw_svga_winsys_buffer_destroy(&vws
->base
, vbuf
);
129 * We couldn't get and map a new buffer for some reason.
130 * Fall through to an ordinary map.
131 * But tell pipe driver to flush now if already on validate list,
132 * Otherwise we'll overwrite previous contents.
134 if (!(flags
& PIPE_TRANSFER_UNSYNCHRONIZED
) &&
135 p_atomic_read(&vsrf
->validated
)) {
141 pb_flags
|= (flags
& PIPE_TRANSFER_DONTBLOCK
);
142 data
= vmw_svga_winsys_buffer_map(&vws
->base
, vsrf
->buf
, pb_flags
);
149 vsrf
->map_mode
= flags
& (PIPE_TRANSFER_READ
| PIPE_TRANSFER_WRITE
);
151 mtx_unlock(&vsrf
->mutex
);
157 vmw_svga_winsys_surface_unmap(struct svga_winsys_context
*swc
,
158 struct svga_winsys_surface
*srf
,
161 struct vmw_svga_winsys_surface
*vsrf
= vmw_svga_winsys_surface(srf
);
162 mtx_lock(&vsrf
->mutex
);
163 if (--vsrf
->mapcount
== 0) {
164 *rebind
= vsrf
->rebind
;
165 vsrf
->rebind
= FALSE
;
169 vmw_svga_winsys_buffer_unmap(&vsrf
->screen
->base
, vsrf
->buf
);
170 mtx_unlock(&vsrf
->mutex
);
174 vmw_svga_winsys_surface_reference(struct vmw_svga_winsys_surface
**pdst
,
175 struct vmw_svga_winsys_surface
*src
)
177 struct pipe_reference
*src_ref
;
178 struct pipe_reference
*dst_ref
;
179 struct vmw_svga_winsys_surface
*dst
;
181 if(pdst
== NULL
|| *pdst
== src
)
186 src_ref
= src
? &src
->refcnt
: NULL
;
187 dst_ref
= dst
? &dst
->refcnt
: NULL
;
189 if (pipe_reference(dst_ref
, src_ref
)) {
191 vmw_svga_winsys_buffer_destroy(&dst
->screen
->base
, dst
->buf
);
192 vmw_ioctl_surface_destroy(dst
->screen
, dst
->sid
);
194 /* to detect dangling pointers */
195 assert(p_atomic_read(&dst
->validated
) == 0);
196 dst
->sid
= SVGA3D_INVALID_ID
;
198 mtx_destroy(&dst
->mutex
);