virgl: remove transfer after transfer_write
[mesa.git] / src / gallium / drivers / virgl / virgl_staging_mgr.c
1 /*
2 * Copyright 2009 VMware, Inc.
3 * Copyright 2019 Collabora Ltd.
4 *
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:
11 *
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
14 * Software.
15 *
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.
23 */
24
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"
30
31 #include "virgl_staging_mgr.h"
32 #include "virgl_resource.h"
33
34 static bool
35 virgl_staging_alloc_buffer(struct virgl_staging_mgr *staging, unsigned min_size)
36 {
37 struct virgl_winsys *vws = staging->vws;
38 unsigned size;
39
40 /* Release the old buffer, if present:
41 */
42 vws->resource_reference(vws, &staging->hw_res, NULL);
43
44 /* Allocate a new one:
45 */
46 size = align(MAX2(staging->default_size, min_size), 4096);
47
48 staging->hw_res = vws->resource_create(vws,
49 PIPE_BUFFER,
50 PIPE_FORMAT_R8_UNORM,
51 VIRGL_BIND_STAGING,
52 size, /* width */
53 1, /* height */
54 1, /* depth */
55 1, /* array_size */
56 0, /* last_level */
57 0, /* nr_samples */
58 size); /* size */
59 if (staging->hw_res == NULL)
60 return false;
61
62 staging->map = vws->resource_map(vws, staging->hw_res);
63 if (staging->map == NULL) {
64 vws->resource_reference(vws, &staging->hw_res, NULL);
65 return false;
66 }
67
68 staging->offset = 0;
69 staging->size = size;
70
71 return true;
72 }
73
74 void
75 virgl_staging_init(struct virgl_staging_mgr *staging, struct pipe_context *pipe,
76 unsigned default_size)
77 {
78 memset(staging, 0, sizeof(*staging));
79
80 staging->vws = virgl_screen(pipe->screen)->vws;
81 staging->default_size = default_size;
82 }
83
84 void
85 virgl_staging_destroy(struct virgl_staging_mgr *staging)
86 {
87 struct virgl_winsys *vws = staging->vws;
88 vws->resource_reference(vws, &staging->hw_res, NULL);
89 }
90
91 bool
92 virgl_staging_alloc(struct virgl_staging_mgr *staging,
93 unsigned size,
94 unsigned alignment,
95 unsigned *out_offset,
96 struct virgl_hw_res **outbuf,
97 void **ptr)
98 {
99 struct virgl_winsys *vws = staging->vws;
100 unsigned offset = align(staging->offset, alignment);
101
102 assert(out_offset);
103 assert(outbuf);
104 assert(ptr);
105 assert(size);
106
107 /* Make sure we have enough space in the staging buffer
108 * for the sub-allocation.
109 */
110 if (offset + size > staging->size) {
111 if (unlikely(!virgl_staging_alloc_buffer(staging, size))) {
112 *out_offset = ~0;
113 vws->resource_reference(vws, outbuf, NULL);
114 *ptr = NULL;
115 return false;
116 }
117
118 offset = 0;
119 }
120
121 assert(staging->size);
122 assert(staging->hw_res);
123 assert(staging->map);
124 assert(offset < staging->size);
125 assert(offset + size <= staging->size);
126
127 /* Emit the return values: */
128 *ptr = staging->map + offset;
129 vws->resource_reference(vws, outbuf, staging->hw_res);
130 *out_offset = offset;
131
132 staging->offset = offset + size;
133
134 return true;
135 }