Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c
4566 views
1
2
#include "i915_drm_winsys.h"
3
#include "util/u_memory.h"
4
5
#include "drm-uapi/i915_drm.h"
6
#include "i915/i915_debug.h"
7
#include <xf86drm.h>
8
#include <stdio.h>
9
10
#define BATCH_RESERVED 16
11
12
#define INTEL_DEFAULT_RELOCS 100
13
#define INTEL_MAX_RELOCS 400
14
15
#define INTEL_BATCH_NO_CLIPRECTS 0x1
16
#define INTEL_BATCH_CLIPRECTS 0x2
17
18
#undef INTEL_RUN_SYNC
19
20
struct i915_drm_batchbuffer
21
{
22
struct i915_winsys_batchbuffer base;
23
24
size_t actual_size;
25
26
drm_intel_bo *bo;
27
};
28
29
static inline struct i915_drm_batchbuffer *
30
i915_drm_batchbuffer(struct i915_winsys_batchbuffer *batch)
31
{
32
return (struct i915_drm_batchbuffer *)batch;
33
}
34
35
static void
36
i915_drm_batchbuffer_reset(struct i915_drm_batchbuffer *batch)
37
{
38
struct i915_drm_winsys *idws = i915_drm_winsys(batch->base.iws);
39
40
if (batch->bo)
41
drm_intel_bo_unreference(batch->bo);
42
batch->bo = drm_intel_bo_alloc(idws->gem_manager,
43
"gallium3d_batchbuffer",
44
batch->actual_size,
45
4096);
46
47
memset(batch->base.map, 0, batch->actual_size);
48
batch->base.ptr = batch->base.map;
49
batch->base.size = batch->actual_size - BATCH_RESERVED;
50
batch->base.relocs = 0;
51
}
52
53
static struct i915_winsys_batchbuffer *
54
i915_drm_batchbuffer_create(struct i915_winsys *iws)
55
{
56
struct i915_drm_winsys *idws = i915_drm_winsys(iws);
57
struct i915_drm_batchbuffer *batch = CALLOC_STRUCT(i915_drm_batchbuffer);
58
59
batch->actual_size = idws->max_batch_size;
60
61
batch->base.map = MALLOC(batch->actual_size);
62
batch->base.ptr = NULL;
63
batch->base.size = 0;
64
65
batch->base.relocs = 0;
66
67
batch->base.iws = iws;
68
69
i915_drm_batchbuffer_reset(batch);
70
71
return &batch->base;
72
}
73
74
static bool
75
i915_drm_batchbuffer_validate_buffers(struct i915_winsys_batchbuffer *batch,
76
struct i915_winsys_buffer **buffer,
77
int num_of_buffers)
78
{
79
struct i915_drm_batchbuffer *drm_batch = i915_drm_batchbuffer(batch);
80
drm_intel_bo *bos[num_of_buffers + 1];
81
int i, ret;
82
83
bos[0] = drm_batch->bo;
84
for (i = 0; i < num_of_buffers; i++)
85
bos[i+1] = intel_bo(buffer[i]);
86
87
ret = drm_intel_bufmgr_check_aperture_space(bos, num_of_buffers);
88
if (ret != 0)
89
return false;
90
91
return true;
92
}
93
94
static int
95
i915_drm_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch,
96
struct i915_winsys_buffer *buffer,
97
enum i915_winsys_buffer_usage usage,
98
unsigned pre_add, bool fenced)
99
{
100
struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
101
unsigned write_domain = 0;
102
unsigned read_domain = 0;
103
unsigned offset;
104
int ret = 0;
105
106
switch (usage) {
107
case I915_USAGE_SAMPLER:
108
write_domain = 0;
109
read_domain = I915_GEM_DOMAIN_SAMPLER;
110
break;
111
case I915_USAGE_RENDER:
112
write_domain = I915_GEM_DOMAIN_RENDER;
113
read_domain = I915_GEM_DOMAIN_RENDER;
114
break;
115
case I915_USAGE_2D_TARGET:
116
write_domain = I915_GEM_DOMAIN_RENDER;
117
read_domain = I915_GEM_DOMAIN_RENDER;
118
break;
119
case I915_USAGE_2D_SOURCE:
120
write_domain = 0;
121
read_domain = I915_GEM_DOMAIN_RENDER;
122
break;
123
case I915_USAGE_VERTEX:
124
write_domain = 0;
125
read_domain = I915_GEM_DOMAIN_VERTEX;
126
break;
127
default:
128
assert(0);
129
return -1;
130
}
131
132
offset = (unsigned)(batch->base.ptr - batch->base.map);
133
134
if (fenced)
135
ret = drm_intel_bo_emit_reloc_fence(batch->bo, offset,
136
intel_bo(buffer), pre_add,
137
read_domain,
138
write_domain);
139
else
140
ret = drm_intel_bo_emit_reloc(batch->bo, offset,
141
intel_bo(buffer), pre_add,
142
read_domain,
143
write_domain);
144
145
((uint32_t*)batch->base.ptr)[0] = intel_bo(buffer)->offset + pre_add;
146
batch->base.ptr += 4;
147
148
if (!ret)
149
batch->base.relocs++;
150
151
return ret;
152
}
153
154
static void
155
i915_drm_throttle(struct i915_drm_winsys *idws)
156
{
157
drmIoctl(idws->fd, DRM_IOCTL_I915_GEM_THROTTLE, NULL);
158
}
159
160
static void
161
i915_drm_batchbuffer_flush(struct i915_winsys_batchbuffer *ibatch,
162
struct pipe_fence_handle **fence,
163
enum i915_winsys_flush_flags flags)
164
{
165
struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
166
unsigned used;
167
int ret;
168
169
/* MI_BATCH_BUFFER_END */
170
i915_winsys_batchbuffer_dword_unchecked(ibatch, (0xA<<23));
171
172
used = batch->base.ptr - batch->base.map;
173
if (used & 4) {
174
/* MI_NOOP */
175
i915_winsys_batchbuffer_dword_unchecked(ibatch, 0);
176
used += 4;
177
}
178
179
/* Do the sending to HW */
180
ret = drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map);
181
if (ret == 0 && i915_drm_winsys(ibatch->iws)->send_cmd)
182
ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
183
184
if (flags & I915_FLUSH_END_OF_FRAME)
185
i915_drm_throttle(i915_drm_winsys(ibatch->iws));
186
187
if (ret != 0 || i915_drm_winsys(ibatch->iws)->dump_cmd) {
188
i915_dump_batchbuffer(ibatch);
189
assert(ret == 0);
190
}
191
192
if (i915_drm_winsys(ibatch->iws)->dump_raw_file) {
193
FILE *file = fopen(i915_drm_winsys(ibatch->iws)->dump_raw_file, "a");
194
if (file) {
195
fwrite(batch->base.map, used, 1, file);
196
fclose(file);
197
}
198
}
199
200
#ifdef INTEL_RUN_SYNC
201
drm_intel_bo_wait_rendering(batch->bo);
202
#endif
203
204
if (fence) {
205
ibatch->iws->fence_reference(ibatch->iws, fence, NULL);
206
207
#ifdef INTEL_RUN_SYNC
208
/* we run synced to GPU so just pass null */
209
(*fence) = i915_drm_fence_create(NULL);
210
#else
211
(*fence) = i915_drm_fence_create(batch->bo);
212
#endif
213
}
214
215
i915_drm_batchbuffer_reset(batch);
216
}
217
218
static void
219
i915_drm_batchbuffer_destroy(struct i915_winsys_batchbuffer *ibatch)
220
{
221
struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
222
223
if (batch->bo)
224
drm_intel_bo_unreference(batch->bo);
225
226
FREE(batch->base.map);
227
FREE(batch);
228
}
229
230
void i915_drm_winsys_init_batchbuffer_functions(struct i915_drm_winsys *idws)
231
{
232
idws->base.batchbuffer_create = i915_drm_batchbuffer_create;
233
idws->base.validate_buffers = i915_drm_batchbuffer_validate_buffers;
234
idws->base.batchbuffer_reloc = i915_drm_batchbuffer_reloc;
235
idws->base.batchbuffer_flush = i915_drm_batchbuffer_flush;
236
idws->base.batchbuffer_destroy = i915_drm_batchbuffer_destroy;
237
}
238
239