2 * Copyright 2009 VMware, Inc.
3 * Copyright 2019 Collabora Ltd.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 #include "pipe/p_defines.h"
26 #include "util/u_inlines.h"
27 #include "pipe/p_context.h"
28 #include "util/u_memory.h"
29 #include "util/u_math.h"
31 #include "virgl_staging_mgr.h"
32 #include "virgl_resource.h"
35 virgl_staging_alloc_buffer(struct virgl_staging_mgr
*staging
, unsigned min_size
)
37 struct virgl_winsys
*vws
= staging
->vws
;
40 /* Release the old buffer, if present:
42 vws
->resource_reference(vws
, &staging
->hw_res
, NULL
);
44 /* Allocate a new one:
46 size
= align(MAX2(staging
->default_size
, min_size
), 4096);
48 staging
->hw_res
= vws
->resource_create(vws
,
59 if (staging
->hw_res
== NULL
)
62 staging
->map
= vws
->resource_map(vws
, staging
->hw_res
);
63 if (staging
->map
== NULL
) {
64 vws
->resource_reference(vws
, &staging
->hw_res
, NULL
);
75 virgl_staging_init(struct virgl_staging_mgr
*staging
, struct pipe_context
*pipe
,
76 unsigned default_size
)
78 memset(staging
, 0, sizeof(*staging
));
80 staging
->vws
= virgl_screen(pipe
->screen
)->vws
;
81 staging
->default_size
= default_size
;
85 virgl_staging_destroy(struct virgl_staging_mgr
*staging
)
87 struct virgl_winsys
*vws
= staging
->vws
;
88 vws
->resource_reference(vws
, &staging
->hw_res
, NULL
);
92 virgl_staging_alloc(struct virgl_staging_mgr
*staging
,
96 struct virgl_hw_res
**outbuf
,
99 struct virgl_winsys
*vws
= staging
->vws
;
100 unsigned offset
= align(staging
->offset
, alignment
);
107 /* Make sure we have enough space in the staging buffer
108 * for the sub-allocation.
110 if (offset
+ size
> staging
->size
) {
111 if (unlikely(!virgl_staging_alloc_buffer(staging
, size
))) {
113 vws
->resource_reference(vws
, outbuf
, NULL
);
121 assert(staging
->size
);
122 assert(staging
->hw_res
);
123 assert(staging
->map
);
124 assert(offset
< staging
->size
);
125 assert(offset
+ size
<= staging
->size
);
127 /* Emit the return values: */
128 *ptr
= staging
->map
+ offset
;
129 vws
->resource_reference(vws
, outbuf
, staging
->hw_res
);
130 *out_offset
= offset
;
132 staging
->offset
= offset
+ size
;