Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/freedreno/drm/msm_bo.c
4564 views
1
/*
2
* Copyright (C) 2012-2018 Rob Clark <[email protected]>
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
* SOFTWARE.
22
*
23
* Authors:
24
* Rob Clark <[email protected]>
25
*/
26
27
#include "msm_priv.h"
28
29
static int
30
bo_allocate(struct msm_bo *msm_bo)
31
{
32
struct fd_bo *bo = &msm_bo->base;
33
if (!msm_bo->offset) {
34
struct drm_msm_gem_info req = {
35
.handle = bo->handle,
36
.info = MSM_INFO_GET_OFFSET,
37
};
38
int ret;
39
40
/* if the buffer is already backed by pages then this
41
* doesn't actually do anything (other than giving us
42
* the offset)
43
*/
44
ret =
45
drmCommandWriteRead(bo->dev->fd, DRM_MSM_GEM_INFO, &req, sizeof(req));
46
if (ret) {
47
ERROR_MSG("alloc failed: %s", strerror(errno));
48
return ret;
49
}
50
51
msm_bo->offset = req.value;
52
}
53
54
return 0;
55
}
56
57
static int
58
msm_bo_offset(struct fd_bo *bo, uint64_t *offset)
59
{
60
struct msm_bo *msm_bo = to_msm_bo(bo);
61
int ret = bo_allocate(msm_bo);
62
if (ret)
63
return ret;
64
*offset = msm_bo->offset;
65
return 0;
66
}
67
68
static int
69
msm_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op)
70
{
71
struct drm_msm_gem_cpu_prep req = {
72
.handle = bo->handle,
73
.op = op,
74
};
75
76
get_abs_timeout(&req.timeout, 5000000000);
77
78
return drmCommandWrite(bo->dev->fd, DRM_MSM_GEM_CPU_PREP, &req, sizeof(req));
79
}
80
81
static void
82
msm_bo_cpu_fini(struct fd_bo *bo)
83
{
84
struct drm_msm_gem_cpu_fini req = {
85
.handle = bo->handle,
86
};
87
88
drmCommandWrite(bo->dev->fd, DRM_MSM_GEM_CPU_FINI, &req, sizeof(req));
89
}
90
91
static int
92
msm_bo_madvise(struct fd_bo *bo, int willneed)
93
{
94
struct drm_msm_gem_madvise req = {
95
.handle = bo->handle,
96
.madv = willneed ? MSM_MADV_WILLNEED : MSM_MADV_DONTNEED,
97
};
98
int ret;
99
100
/* older kernels do not support this: */
101
if (bo->dev->version < FD_VERSION_MADVISE)
102
return willneed;
103
104
ret =
105
drmCommandWriteRead(bo->dev->fd, DRM_MSM_GEM_MADVISE, &req, sizeof(req));
106
if (ret)
107
return ret;
108
109
return req.retained;
110
}
111
112
static uint64_t
113
msm_bo_iova(struct fd_bo *bo)
114
{
115
struct drm_msm_gem_info req = {
116
.handle = bo->handle,
117
.info = MSM_INFO_GET_IOVA,
118
};
119
int ret;
120
121
ret = drmCommandWriteRead(bo->dev->fd, DRM_MSM_GEM_INFO, &req, sizeof(req));
122
if (ret)
123
return 0;
124
125
return req.value;
126
}
127
128
static void
129
msm_bo_set_name(struct fd_bo *bo, const char *fmt, va_list ap)
130
{
131
struct drm_msm_gem_info req = {
132
.handle = bo->handle,
133
.info = MSM_INFO_SET_NAME,
134
};
135
char buf[32];
136
int sz;
137
138
if (bo->dev->version < FD_VERSION_SOFTPIN)
139
return;
140
141
sz = vsnprintf(buf, sizeof(buf), fmt, ap);
142
143
req.value = VOID2U64(buf);
144
req.len = MIN2(sz, sizeof(buf));
145
146
drmCommandWrite(bo->dev->fd, DRM_MSM_GEM_INFO, &req, sizeof(req));
147
}
148
149
static void
150
msm_bo_destroy(struct fd_bo *bo)
151
{
152
struct msm_bo *msm_bo = to_msm_bo(bo);
153
free(msm_bo);
154
}
155
156
static const struct fd_bo_funcs funcs = {
157
.offset = msm_bo_offset,
158
.cpu_prep = msm_bo_cpu_prep,
159
.cpu_fini = msm_bo_cpu_fini,
160
.madvise = msm_bo_madvise,
161
.iova = msm_bo_iova,
162
.set_name = msm_bo_set_name,
163
.destroy = msm_bo_destroy,
164
};
165
166
/* allocate a buffer handle: */
167
int
168
msm_bo_new_handle(struct fd_device *dev, uint32_t size, uint32_t flags,
169
uint32_t *handle)
170
{
171
struct drm_msm_gem_new req = {
172
.size = size,
173
.flags = MSM_BO_WC, // TODO figure out proper flags..
174
};
175
int ret;
176
177
if (flags & FD_BO_SCANOUT)
178
req.flags |= MSM_BO_SCANOUT;
179
180
if (flags & FD_BO_GPUREADONLY)
181
req.flags |= MSM_BO_GPU_READONLY;
182
183
ret = drmCommandWriteRead(dev->fd, DRM_MSM_GEM_NEW, &req, sizeof(req));
184
if (ret)
185
return ret;
186
187
*handle = req.handle;
188
189
return 0;
190
}
191
192
/* allocate a new buffer object */
193
struct fd_bo *
194
msm_bo_from_handle(struct fd_device *dev, uint32_t size, uint32_t handle)
195
{
196
struct msm_bo *msm_bo;
197
struct fd_bo *bo;
198
199
msm_bo = calloc(1, sizeof(*msm_bo));
200
if (!msm_bo)
201
return NULL;
202
203
bo = &msm_bo->base;
204
bo->funcs = &funcs;
205
206
return bo;
207
}
208
209