blob: a53e7e9c9838768666647e923041d30de3f95afa [file] [log] [blame]
Chia-I Wu6464ff22014-08-05 11:59:54 +08001/*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2012-2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the 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 NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
26 */
27
28#include <string.h>
Courtney Goeltzenleuchter8d651042014-09-25 18:15:33 -060029#include <stdlib.h>
Chia-I Wu770b3092014-08-05 14:22:03 +080030#include <limits.h>
Chia-I Wu6464ff22014-08-05 11:59:54 +080031#include <errno.h>
32#ifndef ETIME
33#define ETIME ETIMEDOUT
34#endif
Chia-I Wu770b3092014-08-05 14:22:03 +080035#include <assert.h>
Chia-I Wu6464ff22014-08-05 11:59:54 +080036
37#include <xf86drm.h>
38#include <i915_drm.h>
39#include <intel_bufmgr.h>
40
Chia-I Wuf13ed3c2015-02-22 14:09:00 +080041#include "icd-instance.h"
Chia-I Wu08cd6e92015-02-11 13:44:50 -070042#include "icd-utils.h"
Chia-I Wu770b3092014-08-05 14:22:03 +080043#include "winsys.h"
Chia-I Wu6464ff22014-08-05 11:59:54 +080044
Chia-I Wu6464ff22014-08-05 11:59:54 +080045struct intel_winsys {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +080046 const struct icd_instance *instance;
Chia-I Wu6464ff22014-08-05 11:59:54 +080047 int fd;
48 drm_intel_bufmgr *bufmgr;
49 struct intel_winsys_info info;
50
Chia-I Wu770b3092014-08-05 14:22:03 +080051 drm_intel_context *ctx;
Chia-I Wu6464ff22014-08-05 11:59:54 +080052};
53
54static drm_intel_bo *
55gem_bo(const struct intel_bo *bo)
56{
57 return (drm_intel_bo *) bo;
58}
59
60static bool
61get_param(struct intel_winsys *winsys, int param, int *value)
62{
63 struct drm_i915_getparam gp;
64 int err;
65
66 *value = 0;
67
68 memset(&gp, 0, sizeof(gp));
69 gp.param = param;
70 gp.value = value;
71
72 err = drmCommandWriteRead(winsys->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
73 if (err) {
74 *value = 0;
75 return false;
76 }
77
78 return true;
79}
80
81static bool
82test_address_swizzling(struct intel_winsys *winsys)
83{
84 drm_intel_bo *bo;
85 uint32_t tiling = I915_TILING_X, swizzle;
86 unsigned long pitch;
87
88 bo = drm_intel_bo_alloc_tiled(winsys->bufmgr,
89 "address swizzling test", 64, 64, 4, &tiling, &pitch, 0);
90 if (bo) {
91 drm_intel_bo_get_tiling(bo, &tiling, &swizzle);
92 drm_intel_bo_unreference(bo);
93 }
94 else {
95 swizzle = I915_BIT_6_SWIZZLE_NONE;
96 }
97
98 return (swizzle != I915_BIT_6_SWIZZLE_NONE);
99}
100
101static bool
102test_reg_read(struct intel_winsys *winsys, uint32_t reg)
103{
104 uint64_t dummy;
105
106 return !drm_intel_reg_read(winsys->bufmgr, reg, &dummy);
107}
108
109static bool
110probe_winsys(struct intel_winsys *winsys)
111{
112 struct intel_winsys_info *info = &winsys->info;
113 int val;
114
115 /*
116 * When we need the Nth vertex from a user vertex buffer, and the vertex is
117 * uploaded to, say, the beginning of a bo, we want the first vertex in the
118 * bo to be fetched. One way to do this is to set the base address of the
119 * vertex buffer to
120 *
121 * bo->offset64 + (vb->buffer_offset - vb->stride * N).
122 *
123 * The second term may be negative, and we need kernel support to do that.
124 *
125 * This check is taken from the classic driver. u_vbuf_upload_buffers()
126 * guarantees the term is never negative, but it is good to require a
127 * recent kernel.
128 */
129 get_param(winsys, I915_PARAM_HAS_RELAXED_DELTA, &val);
130 if (!val) {
Chia-I Wu6464ff22014-08-05 11:59:54 +0800131 return false;
132 }
133
134 info->devid = drm_intel_bufmgr_gem_get_devid(winsys->bufmgr);
135
Chia-I Wubbedc592015-02-11 11:10:14 -0700136 if (drm_intel_get_aperture_sizes(winsys->fd,
137 &info->aperture_mappable, &info->aperture_total)) {
138 return false;
139 }
140
Chia-I Wu6464ff22014-08-05 11:59:54 +0800141 get_param(winsys, I915_PARAM_HAS_LLC, &val);
142 info->has_llc = val;
143 info->has_address_swizzling = test_address_swizzling(winsys);
144
Chia-I Wu770b3092014-08-05 14:22:03 +0800145 winsys->ctx = drm_intel_gem_context_create(winsys->bufmgr);
146 if (!winsys->ctx)
147 return false;
148
149 info->has_logical_context = (winsys->ctx != NULL);
Chia-I Wu6464ff22014-08-05 11:59:54 +0800150
151 get_param(winsys, I915_PARAM_HAS_ALIASING_PPGTT, &val);
152 info->has_ppgtt = val;
153
154 /* test TIMESTAMP read */
155 info->has_timestamp = test_reg_read(winsys, 0x2358);
156
157 get_param(winsys, I915_PARAM_HAS_GEN7_SOL_RESET, &val);
158 info->has_gen7_sol_reset = val;
159
160 return true;
161}
162
163struct intel_winsys *
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800164intel_winsys_create_for_fd(const struct icd_instance *instance, int fd)
Chia-I Wu6464ff22014-08-05 11:59:54 +0800165{
Mike Stroyan9fca7122015-02-09 13:08:26 -0700166 /* so that we can have enough relocs per bo */
167 const int batch_size = sizeof(uint32_t) * 150 * 1024;
Chia-I Wu6464ff22014-08-05 11:59:54 +0800168 struct intel_winsys *winsys;
169
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800170 winsys = icd_instance_alloc(instance, sizeof(*winsys), 0,
171 XGL_SYSTEM_ALLOC_INTERNAL);
Chia-I Wu6464ff22014-08-05 11:59:54 +0800172 if (!winsys)
173 return NULL;
174
Chia-I Wu770b3092014-08-05 14:22:03 +0800175 memset(winsys, 0, sizeof(*winsys));
176
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800177 winsys->instance = instance;
Chia-I Wu6464ff22014-08-05 11:59:54 +0800178 winsys->fd = fd;
179
Chia-I Wu32a22462014-08-26 14:13:46 +0800180 winsys->bufmgr = drm_intel_bufmgr_gem_init(winsys->fd, batch_size);
Chia-I Wu6464ff22014-08-05 11:59:54 +0800181 if (!winsys->bufmgr) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800182 icd_instance_free(instance, winsys);
Chia-I Wu6464ff22014-08-05 11:59:54 +0800183 return NULL;
184 }
185
Chia-I Wu6464ff22014-08-05 11:59:54 +0800186 if (!probe_winsys(winsys)) {
Chia-I Wu6464ff22014-08-05 11:59:54 +0800187 drm_intel_bufmgr_destroy(winsys->bufmgr);
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800188 icd_instance_free(instance, winsys);
Chia-I Wu6464ff22014-08-05 11:59:54 +0800189 return NULL;
190 }
191
192 /*
193 * No need to implicitly set up a fence register for each non-linear reloc
Chia-I Wu32a22462014-08-26 14:13:46 +0800194 * entry. INTEL_RELOC_FENCE will be set on reloc entries that need them.
Chia-I Wu6464ff22014-08-05 11:59:54 +0800195 */
196 drm_intel_bufmgr_gem_enable_fenced_relocs(winsys->bufmgr);
197
198 drm_intel_bufmgr_gem_enable_reuse(winsys->bufmgr);
Chia-I Wuaa155ce2015-02-24 10:06:26 -0700199 drm_intel_bufmgr_gem_set_vma_cache_size(winsys->bufmgr, -1);
Chia-I Wu6464ff22014-08-05 11:59:54 +0800200
201 return winsys;
202}
203
204void
205intel_winsys_destroy(struct intel_winsys *winsys)
206{
Chia-I Wu770b3092014-08-05 14:22:03 +0800207 drm_intel_gem_context_destroy(winsys->ctx);
Chia-I Wu6464ff22014-08-05 11:59:54 +0800208 drm_intel_bufmgr_destroy(winsys->bufmgr);
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800209 icd_instance_free(winsys->instance, winsys);
Chia-I Wu6464ff22014-08-05 11:59:54 +0800210}
211
212const struct intel_winsys_info *
213intel_winsys_get_info(const struct intel_winsys *winsys)
214{
215 return &winsys->info;
216}
217
Chia-I Wu6464ff22014-08-05 11:59:54 +0800218int
219intel_winsys_read_reg(struct intel_winsys *winsys,
220 uint32_t reg, uint64_t *val)
221{
222 return drm_intel_reg_read(winsys->bufmgr, reg, val);
223}
224
Chia-I Wucb2dc0d2015-03-05 16:19:42 -0700225int
226intel_winsys_get_reset_stats(struct intel_winsys *winsys,
227 uint32_t *active_lost,
228 uint32_t *pending_lost)
229{
230 uint32_t reset_count;
231
232 return drm_intel_get_reset_stats(winsys->ctx,
233 &reset_count, active_lost, pending_lost);
234}
235
Chia-I Wu6464ff22014-08-05 11:59:54 +0800236struct intel_bo *
237intel_winsys_alloc_bo(struct intel_winsys *winsys,
238 const char *name,
Chia-I Wucb2dc0d2015-03-05 16:19:42 -0700239 unsigned long size,
Chia-I Wu32a22462014-08-26 14:13:46 +0800240 bool cpu_init)
Chia-I Wu6464ff22014-08-05 11:59:54 +0800241{
Chia-I Wu6464ff22014-08-05 11:59:54 +0800242 const unsigned int alignment = 4096; /* always page-aligned */
Chia-I Wu6464ff22014-08-05 11:59:54 +0800243 drm_intel_bo *bo;
244
Chia-I Wu32a22462014-08-26 14:13:46 +0800245 if (cpu_init) {
246 bo = drm_intel_bo_alloc(winsys->bufmgr, name, size, alignment);
Chia-I Wucb2dc0d2015-03-05 16:19:42 -0700247 } else {
Chia-I Wu32a22462014-08-26 14:13:46 +0800248 bo = drm_intel_bo_alloc_for_render(winsys->bufmgr,
249 name, size, alignment);
Chia-I Wu6464ff22014-08-05 11:59:54 +0800250 }
251
Chia-I Wucb2dc0d2015-03-05 16:19:42 -0700252 return (struct intel_bo *) bo;
253}
Chia-I Wu6464ff22014-08-05 11:59:54 +0800254
Chia-I Wucb2dc0d2015-03-05 16:19:42 -0700255struct intel_bo *
256intel_winsys_import_userptr(struct intel_winsys *winsys,
257 const char *name,
258 void *userptr,
259 unsigned long size,
260 unsigned long flags)
261{
262 drm_intel_bo *bo;
263
264 bo = drm_intel_bo_alloc_userptr(winsys->bufmgr, name, userptr,
265 INTEL_TILING_NONE, 0, size, flags);
Chia-I Wu6464ff22014-08-05 11:59:54 +0800266
267 return (struct intel_bo *) bo;
268}
269
270struct intel_bo *
271intel_winsys_import_handle(struct intel_winsys *winsys,
272 const char *name,
Chia-I Wu770b3092014-08-05 14:22:03 +0800273 const struct intel_winsys_handle *handle,
Chia-I Wu6464ff22014-08-05 11:59:54 +0800274 unsigned long height,
275 enum intel_tiling_mode *tiling,
276 unsigned long *pitch)
277{
278 uint32_t real_tiling, swizzle;
279 drm_intel_bo *bo;
280 int err;
281
282 switch (handle->type) {
Chia-I Wu770b3092014-08-05 14:22:03 +0800283 case INTEL_WINSYS_HANDLE_SHARED:
Chia-I Wu6464ff22014-08-05 11:59:54 +0800284 {
285 const uint32_t gem_name = handle->handle;
286 bo = drm_intel_bo_gem_create_from_name(winsys->bufmgr,
287 name, gem_name);
288 }
289 break;
Chia-I Wu770b3092014-08-05 14:22:03 +0800290 case INTEL_WINSYS_HANDLE_FD:
Chia-I Wu6464ff22014-08-05 11:59:54 +0800291 {
292 const int fd = (int) handle->handle;
293 bo = drm_intel_bo_gem_create_from_prime(winsys->bufmgr,
294 fd, height * handle->stride);
295 }
296 break;
297 default:
298 bo = NULL;
299 break;
300 }
301
302 if (!bo)
303 return NULL;
304
305 err = drm_intel_bo_get_tiling(bo, &real_tiling, &swizzle);
306 if (err) {
307 drm_intel_bo_unreference(bo);
308 return NULL;
309 }
310
311 *tiling = real_tiling;
312 *pitch = handle->stride;
313
314 return (struct intel_bo *) bo;
315}
316
317int
318intel_winsys_export_handle(struct intel_winsys *winsys,
319 struct intel_bo *bo,
320 enum intel_tiling_mode tiling,
321 unsigned long pitch,
322 unsigned long height,
Chia-I Wu770b3092014-08-05 14:22:03 +0800323 struct intel_winsys_handle *handle)
Chia-I Wu6464ff22014-08-05 11:59:54 +0800324{
325 int err = 0;
326
327 switch (handle->type) {
Chia-I Wu770b3092014-08-05 14:22:03 +0800328 case INTEL_WINSYS_HANDLE_SHARED:
Chia-I Wu6464ff22014-08-05 11:59:54 +0800329 {
330 uint32_t name;
331
332 err = drm_intel_bo_flink(gem_bo(bo), &name);
333 if (!err)
334 handle->handle = name;
335 }
336 break;
Chia-I Wu770b3092014-08-05 14:22:03 +0800337 case INTEL_WINSYS_HANDLE_KMS:
Chia-I Wu6464ff22014-08-05 11:59:54 +0800338 handle->handle = gem_bo(bo)->handle;
339 break;
Chia-I Wu770b3092014-08-05 14:22:03 +0800340 case INTEL_WINSYS_HANDLE_FD:
Chia-I Wu6464ff22014-08-05 11:59:54 +0800341 {
Chia-I Wuaaebcc52014-09-18 16:11:36 +0800342 uint32_t real_tiling = tiling;
Chia-I Wu6464ff22014-08-05 11:59:54 +0800343 int fd;
344
Chia-I Wuaaebcc52014-09-18 16:11:36 +0800345 err = drm_intel_bo_set_tiling(gem_bo(bo), &real_tiling, pitch);
346 if (!err)
347 err = drm_intel_bo_gem_export_to_prime(gem_bo(bo), &fd);
Chia-I Wu6464ff22014-08-05 11:59:54 +0800348 if (!err)
349 handle->handle = fd;
350 }
351 break;
352 default:
353 err = -EINVAL;
354 break;
355 }
356
357 if (err)
358 return err;
359
360 handle->stride = pitch;
361
362 return 0;
363}
364
365bool
366intel_winsys_can_submit_bo(struct intel_winsys *winsys,
367 struct intel_bo **bo_array,
368 int count)
369{
370 return !drm_intel_bufmgr_check_aperture_space((drm_intel_bo **) bo_array,
371 count);
372}
373
374int
375intel_winsys_submit_bo(struct intel_winsys *winsys,
376 enum intel_ring_type ring,
377 struct intel_bo *bo, int used,
Chia-I Wu6464ff22014-08-05 11:59:54 +0800378 unsigned long flags)
379{
380 const unsigned long exec_flags = (unsigned long) ring | flags;
Chia-I Wu770b3092014-08-05 14:22:03 +0800381 drm_intel_context *ctx;
Chia-I Wu6464ff22014-08-05 11:59:54 +0800382
383 /* logical contexts are only available for the render ring */
Chia-I Wu770b3092014-08-05 14:22:03 +0800384 ctx = (ring == INTEL_RING_RENDER) ? winsys->ctx : NULL;
Chia-I Wu6464ff22014-08-05 11:59:54 +0800385
386 if (ctx) {
387 return drm_intel_gem_bo_context_exec(gem_bo(bo),
Chia-I Wu770b3092014-08-05 14:22:03 +0800388 ctx, used, exec_flags);
Chia-I Wu6464ff22014-08-05 11:59:54 +0800389 }
390 else {
391 return drm_intel_bo_mrb_exec(gem_bo(bo),
392 used, NULL, 0, 0, exec_flags);
393 }
394}
395
396void
397intel_winsys_decode_bo(struct intel_winsys *winsys,
398 struct intel_bo *bo, int used)
399{
Chia-I Wu770b3092014-08-05 14:22:03 +0800400 struct drm_intel_decode *decode;
Chia-I Wu6464ff22014-08-05 11:59:54 +0800401 void *ptr;
402
403 ptr = intel_bo_map(bo, false);
404 if (!ptr) {
Chia-I Wu6464ff22014-08-05 11:59:54 +0800405 return;
406 }
407
Chia-I Wu770b3092014-08-05 14:22:03 +0800408 decode = drm_intel_decode_context_alloc(winsys->info.devid);
409 if (!decode) {
410 intel_bo_unmap(bo);
411 return;
Chia-I Wu6464ff22014-08-05 11:59:54 +0800412 }
413
Chia-I Wu770b3092014-08-05 14:22:03 +0800414 drm_intel_decode_set_output_file(decode, stderr);
415
Chia-I Wu6464ff22014-08-05 11:59:54 +0800416 /* in dwords */
417 used /= 4;
418
Chia-I Wu770b3092014-08-05 14:22:03 +0800419 drm_intel_decode_set_batch_pointer(decode,
Chia-I Wu6464ff22014-08-05 11:59:54 +0800420 ptr, gem_bo(bo)->offset64, used);
421
Chia-I Wu770b3092014-08-05 14:22:03 +0800422 drm_intel_decode(decode);
Courtney Goeltzenleuchter8d651042014-09-25 18:15:33 -0600423 free(decode);
Chia-I Wu6464ff22014-08-05 11:59:54 +0800424 intel_bo_unmap(bo);
425}
426
Chia-I Wucb2dc0d2015-03-05 16:19:42 -0700427struct intel_bo *
428intel_bo_ref(struct intel_bo *bo)
429{
430 if (bo)
431 drm_intel_bo_reference(gem_bo(bo));
432
433 return bo;
434}
435
436void
437intel_bo_unref(struct intel_bo *bo)
438{
439 if (bo)
440 drm_intel_bo_unreference(gem_bo(bo));
441}
442
Chia-I Wu242b35a2015-02-11 11:26:44 -0700443int
Chia-I Wucb2dc0d2015-03-05 16:19:42 -0700444intel_bo_set_tiling(struct intel_bo *bo,
445 enum intel_tiling_mode tiling,
446 unsigned long pitch)
Chia-I Wu242b35a2015-02-11 11:26:44 -0700447{
Chia-I Wucb2dc0d2015-03-05 16:19:42 -0700448 uint32_t real_tiling = tiling;
449 int err;
Chia-I Wu242b35a2015-02-11 11:26:44 -0700450
Chia-I Wucb2dc0d2015-03-05 16:19:42 -0700451 switch (tiling) {
452 case INTEL_TILING_X:
453 if (pitch % 512)
454 return -1;
455 break;
456 case INTEL_TILING_Y:
457 if (pitch % 128)
458 return -1;
459 break;
460 default:
461 break;
462 }
Chia-I Wu6464ff22014-08-05 11:59:54 +0800463
Chia-I Wucb2dc0d2015-03-05 16:19:42 -0700464 err = drm_intel_bo_set_tiling(gem_bo(bo), &real_tiling, pitch);
465 if (err || real_tiling != tiling) {
466 assert(!"tiling mismatch");
467 return -1;
468 }
469
470 return 0;
Chia-I Wu6464ff22014-08-05 11:59:54 +0800471}
472
473void *
474intel_bo_map(struct intel_bo *bo, bool write_enable)
475{
476 int err;
477
478 err = drm_intel_bo_map(gem_bo(bo), write_enable);
479 if (err) {
Chia-I Wu6464ff22014-08-05 11:59:54 +0800480 return NULL;
481 }
482
483 return gem_bo(bo)->virtual;
484}
485
486void *
Chia-I Wu6702e972015-02-25 09:47:10 -0700487intel_bo_map_async(struct intel_bo *bo)
488{
489 int err;
490
491 err = drm_intel_gem_bo_map_unsynchronized_non_gtt(gem_bo(bo));
492 if (err) {
493 return NULL;
494 }
495
496 return gem_bo(bo)->virtual;
497}
498
499void *
Chia-I Wu6464ff22014-08-05 11:59:54 +0800500intel_bo_map_gtt(struct intel_bo *bo)
501{
502 int err;
503
504 err = drm_intel_gem_bo_map_gtt(gem_bo(bo));
505 if (err) {
Chia-I Wu6464ff22014-08-05 11:59:54 +0800506 return NULL;
507 }
508
509 return gem_bo(bo)->virtual;
510}
511
512void *
Chia-I Wu32a22462014-08-26 14:13:46 +0800513intel_bo_map_gtt_async(struct intel_bo *bo)
Chia-I Wu6464ff22014-08-05 11:59:54 +0800514{
515 int err;
516
517 err = drm_intel_gem_bo_map_unsynchronized(gem_bo(bo));
518 if (err) {
Chia-I Wu6464ff22014-08-05 11:59:54 +0800519 return NULL;
520 }
521
522 return gem_bo(bo)->virtual;
523}
524
525void
526intel_bo_unmap(struct intel_bo *bo)
527{
Chia-I Wu08cd6e92015-02-11 13:44:50 -0700528 int err U_ASSERT_ONLY;
Chia-I Wu6464ff22014-08-05 11:59:54 +0800529
530 err = drm_intel_bo_unmap(gem_bo(bo));
531 assert(!err);
532}
533
534int
535intel_bo_pwrite(struct intel_bo *bo, unsigned long offset,
536 unsigned long size, const void *data)
537{
538 return drm_intel_bo_subdata(gem_bo(bo), offset, size, data);
539}
540
541int
542intel_bo_pread(struct intel_bo *bo, unsigned long offset,
543 unsigned long size, void *data)
544{
545 return drm_intel_bo_get_subdata(gem_bo(bo), offset, size, data);
546}
547
548int
549intel_bo_add_reloc(struct intel_bo *bo, uint32_t offset,
550 struct intel_bo *target_bo, uint32_t target_offset,
Chia-I Wu32a22462014-08-26 14:13:46 +0800551 uint32_t flags, uint64_t *presumed_offset)
Chia-I Wu6464ff22014-08-05 11:59:54 +0800552{
Chia-I Wu32a22462014-08-26 14:13:46 +0800553 uint32_t read_domains, write_domain;
Chia-I Wu6464ff22014-08-05 11:59:54 +0800554 int err;
555
Chia-I Wu32a22462014-08-26 14:13:46 +0800556 if (flags & INTEL_RELOC_WRITE) {
557 /*
558 * Because of the translation to domains, INTEL_RELOC_GGTT should only
559 * be set on GEN6 when the bo is written by MI_* or PIPE_CONTROL. The
560 * kernel will translate it back to INTEL_RELOC_GGTT.
561 */
562 write_domain = (flags & INTEL_RELOC_GGTT) ?
563 I915_GEM_DOMAIN_INSTRUCTION : I915_GEM_DOMAIN_RENDER;
564 read_domains = write_domain;
565 } else {
566 write_domain = 0;
567 read_domains = I915_GEM_DOMAIN_RENDER |
568 I915_GEM_DOMAIN_SAMPLER |
569 I915_GEM_DOMAIN_INSTRUCTION |
570 I915_GEM_DOMAIN_VERTEX;
571 }
572
573 if (flags & INTEL_RELOC_FENCE) {
574 err = drm_intel_bo_emit_reloc_fence(gem_bo(bo), offset,
575 gem_bo(target_bo), target_offset,
576 read_domains, write_domain);
577 } else {
578 err = drm_intel_bo_emit_reloc(gem_bo(bo), offset,
579 gem_bo(target_bo), target_offset,
580 read_domains, write_domain);
581 }
Chia-I Wu6464ff22014-08-05 11:59:54 +0800582
583 *presumed_offset = gem_bo(target_bo)->offset64 + target_offset;
584
585 return err;
586}
587
588int
589intel_bo_get_reloc_count(struct intel_bo *bo)
590{
591 return drm_intel_gem_bo_get_reloc_count(gem_bo(bo));
592}
593
594void
595intel_bo_truncate_relocs(struct intel_bo *bo, int start)
596{
597 drm_intel_gem_bo_clear_relocs(gem_bo(bo), start);
598}
599
600bool
601intel_bo_has_reloc(struct intel_bo *bo, struct intel_bo *target_bo)
602{
603 return drm_intel_bo_references(gem_bo(bo), gem_bo(target_bo));
604}
605
606int
607intel_bo_wait(struct intel_bo *bo, int64_t timeout)
608{
Chia-I Wu05a45f82014-10-13 13:20:11 +0800609 int err = 0;
Chia-I Wu6464ff22014-08-05 11:59:54 +0800610
Chia-I Wu05a45f82014-10-13 13:20:11 +0800611 if (timeout >= 0)
612 err = drm_intel_gem_bo_wait(gem_bo(bo), timeout);
613 else
614 drm_intel_bo_wait_rendering(gem_bo(bo));
615
Chia-I Wu6464ff22014-08-05 11:59:54 +0800616 /* consider the bo idle on errors */
617 if (err && err != -ETIME)
618 err = 0;
619
620 return err;
621}