blob: 1b78b66dd77e23f5b632a96ea0f3546ee349d934 [file] [log] [blame]
Chris Wilson54cf91d2010-11-25 18:00:26 +00001/*
2 * Copyright © 2008,2010 Intel Corporation
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
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
25 * Chris Wilson <chris@chris-wilson.co.uk>
26 *
27 */
28
29#include "drmP.h"
30#include "drm.h"
31#include "i915_drm.h"
32#include "i915_drv.h"
33#include "i915_trace.h"
34#include "intel_drv.h"
35
36struct change_domains {
37 uint32_t invalidate_domains;
38 uint32_t flush_domains;
39 uint32_t flush_rings;
40};
41
42/*
43 * Set the next domain for the specified object. This
44 * may not actually perform the necessary flushing/invaliding though,
45 * as that may want to be batched with other set_domain operations
46 *
47 * This is (we hope) the only really tricky part of gem. The goal
48 * is fairly simple -- track which caches hold bits of the object
49 * and make sure they remain coherent. A few concrete examples may
50 * help to explain how it works. For shorthand, we use the notation
51 * (read_domains, write_domain), e.g. (CPU, CPU) to indicate the
52 * a pair of read and write domain masks.
53 *
54 * Case 1: the batch buffer
55 *
56 * 1. Allocated
57 * 2. Written by CPU
58 * 3. Mapped to GTT
59 * 4. Read by GPU
60 * 5. Unmapped from GTT
61 * 6. Freed
62 *
63 * Let's take these a step at a time
64 *
65 * 1. Allocated
66 * Pages allocated from the kernel may still have
67 * cache contents, so we set them to (CPU, CPU) always.
68 * 2. Written by CPU (using pwrite)
69 * The pwrite function calls set_domain (CPU, CPU) and
70 * this function does nothing (as nothing changes)
71 * 3. Mapped by GTT
72 * This function asserts that the object is not
73 * currently in any GPU-based read or write domains
74 * 4. Read by GPU
75 * i915_gem_execbuffer calls set_domain (COMMAND, 0).
76 * As write_domain is zero, this function adds in the
77 * current read domains (CPU+COMMAND, 0).
78 * flush_domains is set to CPU.
79 * invalidate_domains is set to COMMAND
80 * clflush is run to get data out of the CPU caches
81 * then i915_dev_set_domain calls i915_gem_flush to
82 * emit an MI_FLUSH and drm_agp_chipset_flush
83 * 5. Unmapped from GTT
84 * i915_gem_object_unbind calls set_domain (CPU, CPU)
85 * flush_domains and invalidate_domains end up both zero
86 * so no flushing/invalidating happens
87 * 6. Freed
88 * yay, done
89 *
90 * Case 2: The shared render buffer
91 *
92 * 1. Allocated
93 * 2. Mapped to GTT
94 * 3. Read/written by GPU
95 * 4. set_domain to (CPU,CPU)
96 * 5. Read/written by CPU
97 * 6. Read/written by GPU
98 *
99 * 1. Allocated
100 * Same as last example, (CPU, CPU)
101 * 2. Mapped to GTT
102 * Nothing changes (assertions find that it is not in the GPU)
103 * 3. Read/written by GPU
104 * execbuffer calls set_domain (RENDER, RENDER)
105 * flush_domains gets CPU
106 * invalidate_domains gets GPU
107 * clflush (obj)
108 * MI_FLUSH and drm_agp_chipset_flush
109 * 4. set_domain (CPU, CPU)
110 * flush_domains gets GPU
111 * invalidate_domains gets CPU
112 * wait_rendering (obj) to make sure all drawing is complete.
113 * This will include an MI_FLUSH to get the data from GPU
114 * to memory
115 * clflush (obj) to invalidate the CPU cache
116 * Another MI_FLUSH in i915_gem_flush (eliminate this somehow?)
117 * 5. Read/written by CPU
118 * cache lines are loaded and dirtied
119 * 6. Read written by GPU
120 * Same as last GPU access
121 *
122 * Case 3: The constant buffer
123 *
124 * 1. Allocated
125 * 2. Written by CPU
126 * 3. Read by GPU
127 * 4. Updated (written) by CPU again
128 * 5. Read by GPU
129 *
130 * 1. Allocated
131 * (CPU, CPU)
132 * 2. Written by CPU
133 * (CPU, CPU)
134 * 3. Read by GPU
135 * (CPU+RENDER, 0)
136 * flush_domains = CPU
137 * invalidate_domains = RENDER
138 * clflush (obj)
139 * MI_FLUSH
140 * drm_agp_chipset_flush
141 * 4. Updated (written) by CPU again
142 * (CPU, CPU)
143 * flush_domains = 0 (no previous write domain)
144 * invalidate_domains = 0 (no new read domains)
145 * 5. Read by GPU
146 * (CPU+RENDER, 0)
147 * flush_domains = CPU
148 * invalidate_domains = RENDER
149 * clflush (obj)
150 * MI_FLUSH
151 * drm_agp_chipset_flush
152 */
153static void
154i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj,
155 struct intel_ring_buffer *ring,
156 struct change_domains *cd)
157{
158 uint32_t invalidate_domains = 0, flush_domains = 0;
159
160 /*
161 * If the object isn't moving to a new write domain,
162 * let the object stay in multiple read domains
163 */
164 if (obj->base.pending_write_domain == 0)
165 obj->base.pending_read_domains |= obj->base.read_domains;
166
167 /*
168 * Flush the current write domain if
169 * the new read domains don't match. Invalidate
170 * any read domains which differ from the old
171 * write domain
172 */
173 if (obj->base.write_domain &&
174 (((obj->base.write_domain != obj->base.pending_read_domains ||
175 obj->ring != ring)) ||
176 (obj->fenced_gpu_access && !obj->pending_fenced_gpu_access))) {
177 flush_domains |= obj->base.write_domain;
178 invalidate_domains |=
179 obj->base.pending_read_domains & ~obj->base.write_domain;
180 }
181 /*
182 * Invalidate any read caches which may have
183 * stale data. That is, any new read domains.
184 */
185 invalidate_domains |= obj->base.pending_read_domains & ~obj->base.read_domains;
186 if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU)
187 i915_gem_clflush_object(obj);
188
189 /* blow away mappings if mapped through GTT */
190 if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_GTT)
191 i915_gem_release_mmap(obj);
192
193 /* The actual obj->write_domain will be updated with
194 * pending_write_domain after we emit the accumulated flush for all
195 * of our domain changes in execbuffers (which clears objects'
196 * write_domains). So if we have a current write domain that we
197 * aren't changing, set pending_write_domain to that.
198 */
199 if (flush_domains == 0 && obj->base.pending_write_domain == 0)
200 obj->base.pending_write_domain = obj->base.write_domain;
201
202 cd->invalidate_domains |= invalidate_domains;
203 cd->flush_domains |= flush_domains;
204 if (flush_domains & I915_GEM_GPU_DOMAINS)
205 cd->flush_rings |= obj->ring->id;
206 if (invalidate_domains & I915_GEM_GPU_DOMAINS)
207 cd->flush_rings |= ring->id;
208}
209
Chris Wilson67731b82010-12-08 10:38:14 +0000210struct eb_objects {
211 int and;
212 struct hlist_head buckets[0];
213};
214
215static struct eb_objects *
216eb_create(int size)
217{
218 struct eb_objects *eb;
219 int count = PAGE_SIZE / sizeof(struct hlist_head) / 2;
220 while (count > size)
221 count >>= 1;
222 eb = kzalloc(count*sizeof(struct hlist_head) +
223 sizeof(struct eb_objects),
224 GFP_KERNEL);
225 if (eb == NULL)
226 return eb;
227
228 eb->and = count - 1;
229 return eb;
230}
231
232static void
233eb_reset(struct eb_objects *eb)
234{
235 memset(eb->buckets, 0, (eb->and+1)*sizeof(struct hlist_head));
236}
237
238static void
239eb_add_object(struct eb_objects *eb, struct drm_i915_gem_object *obj)
240{
241 hlist_add_head(&obj->exec_node,
242 &eb->buckets[obj->exec_handle & eb->and]);
243}
244
245static struct drm_i915_gem_object *
246eb_get_object(struct eb_objects *eb, unsigned long handle)
247{
248 struct hlist_head *head;
249 struct hlist_node *node;
250 struct drm_i915_gem_object *obj;
251
252 head = &eb->buckets[handle & eb->and];
253 hlist_for_each(node, head) {
254 obj = hlist_entry(node, struct drm_i915_gem_object, exec_node);
255 if (obj->exec_handle == handle)
256 return obj;
257 }
258
259 return NULL;
260}
261
262static void
263eb_destroy(struct eb_objects *eb)
264{
265 kfree(eb);
266}
267
Chris Wilson54cf91d2010-11-25 18:00:26 +0000268static int
269i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
Chris Wilson67731b82010-12-08 10:38:14 +0000270 struct eb_objects *eb,
Chris Wilson54cf91d2010-11-25 18:00:26 +0000271 struct drm_i915_gem_exec_object2 *entry,
272 struct drm_i915_gem_relocation_entry *reloc)
273{
274 struct drm_device *dev = obj->base.dev;
275 struct drm_gem_object *target_obj;
276 uint32_t target_offset;
277 int ret = -EINVAL;
278
Chris Wilson67731b82010-12-08 10:38:14 +0000279 /* we've already hold a reference to all valid objects */
280 target_obj = &eb_get_object(eb, reloc->target_handle)->base;
281 if (unlikely(target_obj == NULL))
Chris Wilson54cf91d2010-11-25 18:00:26 +0000282 return -ENOENT;
283
284 target_offset = to_intel_bo(target_obj)->gtt_offset;
285
286#if WATCH_RELOC
287 DRM_INFO("%s: obj %p offset %08x target %d "
288 "read %08x write %08x gtt %08x "
289 "presumed %08x delta %08x\n",
290 __func__,
291 obj,
292 (int) reloc->offset,
293 (int) reloc->target_handle,
294 (int) reloc->read_domains,
295 (int) reloc->write_domain,
296 (int) target_offset,
297 (int) reloc->presumed_offset,
298 reloc->delta);
299#endif
300
301 /* The target buffer should have appeared before us in the
302 * exec_object list, so it should have a GTT space bound by now.
303 */
Chris Wilsonb8f7ab12010-12-08 10:43:06 +0000304 if (unlikely(target_offset == 0)) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000305 DRM_ERROR("No GTT space found for object %d\n",
306 reloc->target_handle);
Chris Wilson67731b82010-12-08 10:38:14 +0000307 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000308 }
309
310 /* Validate that the target is in a valid r/w GPU domain */
Chris Wilsonb8f7ab12010-12-08 10:43:06 +0000311 if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000312 DRM_ERROR("reloc with multiple write domains: "
313 "obj %p target %d offset %d "
314 "read %08x write %08x",
315 obj, reloc->target_handle,
316 (int) reloc->offset,
317 reloc->read_domains,
318 reloc->write_domain);
Chris Wilson67731b82010-12-08 10:38:14 +0000319 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000320 }
Chris Wilsonb8f7ab12010-12-08 10:43:06 +0000321 if (unlikely((reloc->write_domain | reloc->read_domains) & I915_GEM_DOMAIN_CPU)) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000322 DRM_ERROR("reloc with read/write CPU domains: "
323 "obj %p target %d offset %d "
324 "read %08x write %08x",
325 obj, reloc->target_handle,
326 (int) reloc->offset,
327 reloc->read_domains,
328 reloc->write_domain);
Chris Wilson67731b82010-12-08 10:38:14 +0000329 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000330 }
Chris Wilsonb8f7ab12010-12-08 10:43:06 +0000331 if (unlikely(reloc->write_domain && target_obj->pending_write_domain &&
332 reloc->write_domain != target_obj->pending_write_domain)) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000333 DRM_ERROR("Write domain conflict: "
334 "obj %p target %d offset %d "
335 "new %08x old %08x\n",
336 obj, reloc->target_handle,
337 (int) reloc->offset,
338 reloc->write_domain,
339 target_obj->pending_write_domain);
Chris Wilson67731b82010-12-08 10:38:14 +0000340 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000341 }
342
343 target_obj->pending_read_domains |= reloc->read_domains;
344 target_obj->pending_write_domain |= reloc->write_domain;
345
346 /* If the relocation already has the right value in it, no
347 * more work needs to be done.
348 */
349 if (target_offset == reloc->presumed_offset)
Chris Wilson67731b82010-12-08 10:38:14 +0000350 return 0;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000351
352 /* Check that the relocation address is valid... */
Chris Wilsonb8f7ab12010-12-08 10:43:06 +0000353 if (unlikely(reloc->offset > obj->base.size - 4)) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000354 DRM_ERROR("Relocation beyond object bounds: "
355 "obj %p target %d offset %d size %d.\n",
356 obj, reloc->target_handle,
357 (int) reloc->offset,
358 (int) obj->base.size);
Chris Wilson67731b82010-12-08 10:38:14 +0000359 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000360 }
Chris Wilsonb8f7ab12010-12-08 10:43:06 +0000361 if (unlikely(reloc->offset & 3)) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000362 DRM_ERROR("Relocation not 4-byte aligned: "
363 "obj %p target %d offset %d.\n",
364 obj, reloc->target_handle,
365 (int) reloc->offset);
Chris Wilson67731b82010-12-08 10:38:14 +0000366 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000367 }
368
369 /* and points to somewhere within the target object. */
Chris Wilsonb8f7ab12010-12-08 10:43:06 +0000370 if (unlikely(reloc->delta >= target_obj->size)) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000371 DRM_ERROR("Relocation beyond target object bounds: "
372 "obj %p target %d delta %d size %d.\n",
373 obj, reloc->target_handle,
374 (int) reloc->delta,
375 (int) target_obj->size);
Chris Wilson67731b82010-12-08 10:38:14 +0000376 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000377 }
378
379 reloc->delta += target_offset;
380 if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) {
381 uint32_t page_offset = reloc->offset & ~PAGE_MASK;
382 char *vaddr;
383
384 vaddr = kmap_atomic(obj->pages[reloc->offset >> PAGE_SHIFT]);
385 *(uint32_t *)(vaddr + page_offset) = reloc->delta;
386 kunmap_atomic(vaddr);
387 } else {
388 struct drm_i915_private *dev_priv = dev->dev_private;
389 uint32_t __iomem *reloc_entry;
390 void __iomem *reloc_page;
391
392 ret = i915_gem_object_set_to_gtt_domain(obj, 1);
393 if (ret)
Chris Wilson67731b82010-12-08 10:38:14 +0000394 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000395
396 /* Map the page containing the relocation we're going to perform. */
397 reloc->offset += obj->gtt_offset;
398 reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
399 reloc->offset & PAGE_MASK);
400 reloc_entry = (uint32_t __iomem *)
401 (reloc_page + (reloc->offset & ~PAGE_MASK));
402 iowrite32(reloc->delta, reloc_entry);
403 io_mapping_unmap_atomic(reloc_page);
404 }
405
406 /* and update the user's relocation entry */
407 reloc->presumed_offset = target_offset;
408
Chris Wilson67731b82010-12-08 10:38:14 +0000409 return 0;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000410}
411
412static int
413i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj,
Chris Wilson67731b82010-12-08 10:38:14 +0000414 struct eb_objects *eb,
Chris Wilson54cf91d2010-11-25 18:00:26 +0000415 struct drm_i915_gem_exec_object2 *entry)
416{
417 struct drm_i915_gem_relocation_entry __user *user_relocs;
418 int i, ret;
419
420 user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr;
421 for (i = 0; i < entry->relocation_count; i++) {
422 struct drm_i915_gem_relocation_entry reloc;
423
424 if (__copy_from_user_inatomic(&reloc,
425 user_relocs+i,
426 sizeof(reloc)))
427 return -EFAULT;
428
Chris Wilson67731b82010-12-08 10:38:14 +0000429 ret = i915_gem_execbuffer_relocate_entry(obj, eb, entry, &reloc);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000430 if (ret)
431 return ret;
432
433 if (__copy_to_user_inatomic(&user_relocs[i].presumed_offset,
434 &reloc.presumed_offset,
435 sizeof(reloc.presumed_offset)))
436 return -EFAULT;
437 }
438
439 return 0;
440}
441
442static int
443i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj,
Chris Wilson67731b82010-12-08 10:38:14 +0000444 struct eb_objects *eb,
Chris Wilson54cf91d2010-11-25 18:00:26 +0000445 struct drm_i915_gem_exec_object2 *entry,
446 struct drm_i915_gem_relocation_entry *relocs)
447{
448 int i, ret;
449
450 for (i = 0; i < entry->relocation_count; i++) {
Chris Wilson67731b82010-12-08 10:38:14 +0000451 ret = i915_gem_execbuffer_relocate_entry(obj, eb, entry, &relocs[i]);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000452 if (ret)
453 return ret;
454 }
455
456 return 0;
457}
458
459static int
460i915_gem_execbuffer_relocate(struct drm_device *dev,
Chris Wilson67731b82010-12-08 10:38:14 +0000461 struct eb_objects *eb,
Chris Wilson432e58e2010-11-25 19:32:06 +0000462 struct list_head *objects,
463 struct drm_i915_gem_exec_object2 *exec)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000464{
Chris Wilson432e58e2010-11-25 19:32:06 +0000465 struct drm_i915_gem_object *obj;
466 int ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000467
Chris Wilson432e58e2010-11-25 19:32:06 +0000468 list_for_each_entry(obj, objects, exec_list) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000469 obj->base.pending_read_domains = 0;
470 obj->base.pending_write_domain = 0;
Chris Wilson67731b82010-12-08 10:38:14 +0000471 ret = i915_gem_execbuffer_relocate_object(obj, eb, exec++);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000472 if (ret)
473 return ret;
474 }
475
476 return 0;
477}
478
479static int
Chris Wilsond9e86c02010-11-10 16:40:20 +0000480i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
Chris Wilson54cf91d2010-11-25 18:00:26 +0000481 struct drm_file *file,
Chris Wilson432e58e2010-11-25 19:32:06 +0000482 struct list_head *objects,
483 struct drm_i915_gem_exec_object2 *exec)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000484{
Chris Wilson432e58e2010-11-25 19:32:06 +0000485 struct drm_i915_gem_object *obj;
486 struct drm_i915_gem_exec_object2 *entry;
487 int ret, retry;
Chris Wilson9b3826b2010-12-05 17:11:54 +0000488 bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000489
490 /* Attempt to pin all of the buffers into the GTT.
491 * This is done in 3 phases:
492 *
493 * 1a. Unbind all objects that do not match the GTT constraints for
494 * the execbuffer (fenceable, mappable, alignment etc).
495 * 1b. Increment pin count for already bound objects.
496 * 2. Bind new objects.
497 * 3. Decrement pin count.
498 *
499 * This avoid unnecessary unbinding of later objects in order to makr
500 * room for the earlier objects *unless* we need to defragment.
501 */
502 retry = 0;
503 do {
504 ret = 0;
505
506 /* Unbind any ill-fitting objects or pin. */
Chris Wilson432e58e2010-11-25 19:32:06 +0000507 entry = exec;
508 list_for_each_entry(obj, objects, exec_list) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000509 bool need_fence, need_mappable;
510
Chris Wilson432e58e2010-11-25 19:32:06 +0000511 if (!obj->gtt_space) {
512 entry++;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000513 continue;
Chris Wilson432e58e2010-11-25 19:32:06 +0000514 }
Chris Wilson54cf91d2010-11-25 18:00:26 +0000515
516 need_fence =
Chris Wilson9b3826b2010-12-05 17:11:54 +0000517 has_fenced_gpu_access &&
Chris Wilson54cf91d2010-11-25 18:00:26 +0000518 entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
519 obj->tiling_mode != I915_TILING_NONE;
520 need_mappable =
521 entry->relocation_count ? true : need_fence;
522
523 if ((entry->alignment && obj->gtt_offset & (entry->alignment - 1)) ||
524 (need_mappable && !obj->map_and_fenceable))
525 ret = i915_gem_object_unbind(obj);
526 else
527 ret = i915_gem_object_pin(obj,
528 entry->alignment,
529 need_mappable);
Chris Wilson432e58e2010-11-25 19:32:06 +0000530 if (ret)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000531 goto err;
Chris Wilson432e58e2010-11-25 19:32:06 +0000532
533 entry++;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000534 }
535
536 /* Bind fresh objects */
Chris Wilson432e58e2010-11-25 19:32:06 +0000537 entry = exec;
538 list_for_each_entry(obj, objects, exec_list) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000539 bool need_fence;
540
541 need_fence =
Chris Wilson9b3826b2010-12-05 17:11:54 +0000542 has_fenced_gpu_access &&
Chris Wilson54cf91d2010-11-25 18:00:26 +0000543 entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
544 obj->tiling_mode != I915_TILING_NONE;
545
546 if (!obj->gtt_space) {
547 bool need_mappable =
548 entry->relocation_count ? true : need_fence;
549
550 ret = i915_gem_object_pin(obj,
551 entry->alignment,
552 need_mappable);
553 if (ret)
554 break;
555 }
556
Chris Wilson9b3826b2010-12-05 17:11:54 +0000557 if (has_fenced_gpu_access) {
558 if (need_fence) {
559 ret = i915_gem_object_get_fence(obj, ring, 1);
560 if (ret)
561 break;
562 } else if (entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
563 obj->tiling_mode == I915_TILING_NONE) {
564 /* XXX pipelined! */
565 ret = i915_gem_object_put_fence(obj);
566 if (ret)
567 break;
568 }
569 obj->pending_fenced_gpu_access = need_fence;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000570 }
571
572 entry->offset = obj->gtt_offset;
Chris Wilson432e58e2010-11-25 19:32:06 +0000573 entry++;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000574 }
575
Chris Wilson432e58e2010-11-25 19:32:06 +0000576 /* Decrement pin count for bound objects */
577 list_for_each_entry(obj, objects, exec_list) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000578 if (obj->gtt_space)
579 i915_gem_object_unpin(obj);
580 }
581
582 if (ret != -ENOSPC || retry > 1)
583 return ret;
584
585 /* First attempt, just clear anything that is purgeable.
586 * Second attempt, clear the entire GTT.
587 */
Chris Wilsond9e86c02010-11-10 16:40:20 +0000588 ret = i915_gem_evict_everything(ring->dev, retry == 0);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000589 if (ret)
590 return ret;
591
592 retry++;
593 } while (1);
Chris Wilson432e58e2010-11-25 19:32:06 +0000594
595err:
Chris Wilson602606a2010-11-28 15:31:02 +0000596 obj = list_entry(obj->exec_list.prev,
597 struct drm_i915_gem_object,
598 exec_list);
Chris Wilson432e58e2010-11-25 19:32:06 +0000599 while (objects != &obj->exec_list) {
600 if (obj->gtt_space)
601 i915_gem_object_unpin(obj);
602
603 obj = list_entry(obj->exec_list.prev,
604 struct drm_i915_gem_object,
605 exec_list);
606 }
607
608 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000609}
610
611static int
612i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
613 struct drm_file *file,
Chris Wilsond9e86c02010-11-10 16:40:20 +0000614 struct intel_ring_buffer *ring,
Chris Wilson432e58e2010-11-25 19:32:06 +0000615 struct list_head *objects,
Chris Wilson67731b82010-12-08 10:38:14 +0000616 struct eb_objects *eb,
Chris Wilson432e58e2010-11-25 19:32:06 +0000617 struct drm_i915_gem_exec_object2 *exec,
Chris Wilson54cf91d2010-11-25 18:00:26 +0000618 int count)
619{
620 struct drm_i915_gem_relocation_entry *reloc;
Chris Wilson432e58e2010-11-25 19:32:06 +0000621 struct drm_i915_gem_object *obj;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000622 int i, total, ret;
623
Chris Wilson67731b82010-12-08 10:38:14 +0000624 /* We may process another execbuffer during the unlock... */
625 while (list_empty(objects)) {
626 obj = list_first_entry(objects,
627 struct drm_i915_gem_object,
628 exec_list);
629 list_del_init(&obj->exec_list);
630 drm_gem_object_unreference(&obj->base);
631 }
632
Chris Wilson54cf91d2010-11-25 18:00:26 +0000633 mutex_unlock(&dev->struct_mutex);
634
635 total = 0;
636 for (i = 0; i < count; i++)
Chris Wilson432e58e2010-11-25 19:32:06 +0000637 total += exec[i].relocation_count;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000638
639 reloc = drm_malloc_ab(total, sizeof(*reloc));
640 if (reloc == NULL) {
641 mutex_lock(&dev->struct_mutex);
642 return -ENOMEM;
643 }
644
645 total = 0;
646 for (i = 0; i < count; i++) {
647 struct drm_i915_gem_relocation_entry __user *user_relocs;
648
Chris Wilson432e58e2010-11-25 19:32:06 +0000649 user_relocs = (void __user *)(uintptr_t)exec[i].relocs_ptr;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000650
651 if (copy_from_user(reloc+total, user_relocs,
Chris Wilson432e58e2010-11-25 19:32:06 +0000652 exec[i].relocation_count * sizeof(*reloc))) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000653 ret = -EFAULT;
654 mutex_lock(&dev->struct_mutex);
655 goto err;
656 }
657
Chris Wilson432e58e2010-11-25 19:32:06 +0000658 total += exec[i].relocation_count;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000659 }
660
661 ret = i915_mutex_lock_interruptible(dev);
662 if (ret) {
663 mutex_lock(&dev->struct_mutex);
664 goto err;
665 }
666
Chris Wilson67731b82010-12-08 10:38:14 +0000667 /* reacquire the objects */
668 INIT_LIST_HEAD(objects);
669 eb_reset(eb);
670 for (i = 0; i < count; i++) {
671 struct drm_i915_gem_object *obj;
672
673 obj = to_intel_bo(drm_gem_object_lookup(dev, file,
674 exec[i].handle));
675 if (obj == NULL) {
676 DRM_ERROR("Invalid object handle %d at index %d\n",
677 exec[i].handle, i);
678 ret = -ENOENT;
679 goto err;
680 }
681
682 list_add_tail(&obj->exec_list, objects);
683 obj->exec_handle = exec[i].handle;
684 eb_add_object(eb, obj);
685 }
686
Chris Wilsond9e86c02010-11-10 16:40:20 +0000687 ret = i915_gem_execbuffer_reserve(ring, file, objects, exec);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000688 if (ret)
689 goto err;
690
691 total = 0;
Chris Wilson432e58e2010-11-25 19:32:06 +0000692 list_for_each_entry(obj, objects, exec_list) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000693 obj->base.pending_read_domains = 0;
694 obj->base.pending_write_domain = 0;
Chris Wilson67731b82010-12-08 10:38:14 +0000695 ret = i915_gem_execbuffer_relocate_object_slow(obj, eb,
Chris Wilson432e58e2010-11-25 19:32:06 +0000696 exec,
Chris Wilson54cf91d2010-11-25 18:00:26 +0000697 reloc + total);
698 if (ret)
699 goto err;
700
Chris Wilson432e58e2010-11-25 19:32:06 +0000701 total += exec->relocation_count;
702 exec++;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000703 }
704
705 /* Leave the user relocations as are, this is the painfully slow path,
706 * and we want to avoid the complication of dropping the lock whilst
707 * having buffers reserved in the aperture and so causing spurious
708 * ENOSPC for random operations.
709 */
710
711err:
712 drm_free_large(reloc);
713 return ret;
714}
715
716static void
717i915_gem_execbuffer_flush(struct drm_device *dev,
718 uint32_t invalidate_domains,
719 uint32_t flush_domains,
720 uint32_t flush_rings)
721{
722 drm_i915_private_t *dev_priv = dev->dev_private;
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000723 int i;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000724
725 if (flush_domains & I915_GEM_DOMAIN_CPU)
726 intel_gtt_chipset_flush();
727
Chris Wilson63256ec2011-01-04 18:42:07 +0000728 if (flush_domains & I915_GEM_DOMAIN_GTT)
729 wmb();
730
Chris Wilson54cf91d2010-11-25 18:00:26 +0000731 if ((flush_domains | invalidate_domains) & I915_GEM_GPU_DOMAINS) {
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000732 for (i = 0; i < I915_NUM_RINGS; i++)
733 if (flush_rings & (1 << i))
734 i915_gem_flush_ring(dev, &dev_priv->ring[i],
735 invalidate_domains,
736 flush_domains);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000737 }
738}
739
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000740static int
741i915_gem_execbuffer_sync_rings(struct drm_i915_gem_object *obj,
742 struct intel_ring_buffer *to)
743{
744 struct intel_ring_buffer *from = obj->ring;
745 u32 seqno;
746 int ret, idx;
747
748 if (from == NULL || to == from)
749 return 0;
750
751 if (INTEL_INFO(obj->base.dev)->gen < 6)
752 return i915_gem_object_wait_rendering(obj, true);
753
754 idx = intel_ring_sync_index(from, to);
755
756 seqno = obj->last_rendering_seqno;
757 if (seqno <= from->sync_seqno[idx])
758 return 0;
759
760 if (seqno == from->outstanding_lazy_request) {
761 struct drm_i915_gem_request *request;
762
763 request = kzalloc(sizeof(*request), GFP_KERNEL);
764 if (request == NULL)
765 return -ENOMEM;
766
767 ret = i915_add_request(obj->base.dev, NULL, request, from);
768 if (ret) {
769 kfree(request);
770 return ret;
771 }
772
773 seqno = request->seqno;
774 }
775
776 from->sync_seqno[idx] = seqno;
777 return intel_ring_sync(to, from, seqno - 1);
778}
Chris Wilson54cf91d2010-11-25 18:00:26 +0000779
780static int
Chris Wilson432e58e2010-11-25 19:32:06 +0000781i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring,
782 struct list_head *objects)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000783{
Chris Wilson432e58e2010-11-25 19:32:06 +0000784 struct drm_i915_gem_object *obj;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000785 struct change_domains cd;
Chris Wilson432e58e2010-11-25 19:32:06 +0000786 int ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000787
788 cd.invalidate_domains = 0;
789 cd.flush_domains = 0;
790 cd.flush_rings = 0;
Chris Wilson432e58e2010-11-25 19:32:06 +0000791 list_for_each_entry(obj, objects, exec_list)
792 i915_gem_object_set_to_gpu_domain(obj, ring, &cd);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000793
794 if (cd.invalidate_domains | cd.flush_domains) {
795#if WATCH_EXEC
796 DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n",
797 __func__,
798 cd.invalidate_domains,
799 cd.flush_domains);
800#endif
Chris Wilson432e58e2010-11-25 19:32:06 +0000801 i915_gem_execbuffer_flush(ring->dev,
Chris Wilson54cf91d2010-11-25 18:00:26 +0000802 cd.invalidate_domains,
803 cd.flush_domains,
804 cd.flush_rings);
805 }
806
Chris Wilson432e58e2010-11-25 19:32:06 +0000807 list_for_each_entry(obj, objects, exec_list) {
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000808 ret = i915_gem_execbuffer_sync_rings(obj, ring);
809 if (ret)
810 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000811 }
812
813 return 0;
814}
815
Chris Wilson432e58e2010-11-25 19:32:06 +0000816static bool
817i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000818{
Chris Wilson432e58e2010-11-25 19:32:06 +0000819 return ((exec->batch_start_offset | exec->batch_len) & 0x7) == 0;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000820}
821
822static int
823validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
824 int count)
825{
826 int i;
827
828 for (i = 0; i < count; i++) {
829 char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr;
830 int length; /* limited by fault_in_pages_readable() */
831
832 /* First check for malicious input causing overflow */
833 if (exec[i].relocation_count >
834 INT_MAX / sizeof(struct drm_i915_gem_relocation_entry))
835 return -EINVAL;
836
837 length = exec[i].relocation_count *
838 sizeof(struct drm_i915_gem_relocation_entry);
839 if (!access_ok(VERIFY_READ, ptr, length))
840 return -EFAULT;
841
842 /* we may also need to update the presumed offsets */
843 if (!access_ok(VERIFY_WRITE, ptr, length))
844 return -EFAULT;
845
846 if (fault_in_pages_readable(ptr, length))
847 return -EFAULT;
848 }
849
850 return 0;
851}
852
Chris Wilson432e58e2010-11-25 19:32:06 +0000853static int
854i915_gem_execbuffer_wait_for_flips(struct intel_ring_buffer *ring,
855 struct list_head *objects)
856{
857 struct drm_i915_gem_object *obj;
858 int flips;
859
860 /* Check for any pending flips. As we only maintain a flip queue depth
861 * of 1, we can simply insert a WAIT for the next display flip prior
862 * to executing the batch and avoid stalling the CPU.
863 */
864 flips = 0;
865 list_for_each_entry(obj, objects, exec_list) {
866 if (obj->base.write_domain)
867 flips |= atomic_read(&obj->pending_flip);
868 }
869 if (flips) {
870 int plane, flip_mask, ret;
871
872 for (plane = 0; flips >> plane; plane++) {
873 if (((flips >> plane) & 1) == 0)
874 continue;
875
876 if (plane)
877 flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
878 else
879 flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
880
881 ret = intel_ring_begin(ring, 2);
882 if (ret)
883 return ret;
884
885 intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask);
886 intel_ring_emit(ring, MI_NOOP);
887 intel_ring_advance(ring);
888 }
889 }
890
891 return 0;
892}
893
894static void
895i915_gem_execbuffer_move_to_active(struct list_head *objects,
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000896 struct intel_ring_buffer *ring,
897 u32 seqno)
Chris Wilson432e58e2010-11-25 19:32:06 +0000898{
899 struct drm_i915_gem_object *obj;
900
901 list_for_each_entry(obj, objects, exec_list) {
902 obj->base.read_domains = obj->base.pending_read_domains;
903 obj->base.write_domain = obj->base.pending_write_domain;
904 obj->fenced_gpu_access = obj->pending_fenced_gpu_access;
905
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000906 i915_gem_object_move_to_active(obj, ring, seqno);
Chris Wilson432e58e2010-11-25 19:32:06 +0000907 if (obj->base.write_domain) {
908 obj->dirty = 1;
Chris Wilson87ca9c82010-12-02 09:42:56 +0000909 obj->pending_gpu_write = true;
Chris Wilson432e58e2010-11-25 19:32:06 +0000910 list_move_tail(&obj->gpu_write_list,
911 &ring->gpu_write_list);
912 intel_mark_busy(ring->dev, obj);
913 }
914
915 trace_i915_gem_object_change_domain(obj,
916 obj->base.read_domains,
917 obj->base.write_domain);
918 }
919}
920
Chris Wilson54cf91d2010-11-25 18:00:26 +0000921static void
922i915_gem_execbuffer_retire_commands(struct drm_device *dev,
Chris Wilson432e58e2010-11-25 19:32:06 +0000923 struct drm_file *file,
Chris Wilson54cf91d2010-11-25 18:00:26 +0000924 struct intel_ring_buffer *ring)
925{
Chris Wilson432e58e2010-11-25 19:32:06 +0000926 struct drm_i915_gem_request *request;
Chris Wilsonb72f3ac2011-01-04 17:34:02 +0000927 u32 invalidate;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000928
Chris Wilson432e58e2010-11-25 19:32:06 +0000929 /*
930 * Ensure that the commands in the batch buffer are
931 * finished before the interrupt fires.
932 *
933 * The sampler always gets flushed on i965 (sigh).
934 */
Chris Wilsonb72f3ac2011-01-04 17:34:02 +0000935 invalidate = I915_GEM_DOMAIN_COMMAND;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000936 if (INTEL_INFO(dev)->gen >= 4)
Chris Wilsonb72f3ac2011-01-04 17:34:02 +0000937 invalidate |= I915_GEM_DOMAIN_SAMPLER;
938 if (ring->flush(ring, invalidate, 0)) {
939 i915_gem_next_request_seqno(dev, ring);
940 return;
941 }
Chris Wilson54cf91d2010-11-25 18:00:26 +0000942
Chris Wilson432e58e2010-11-25 19:32:06 +0000943 /* Add a breadcrumb for the completion of the batch buffer */
944 request = kzalloc(sizeof(*request), GFP_KERNEL);
945 if (request == NULL || i915_add_request(dev, file, request, ring)) {
946 i915_gem_next_request_seqno(dev, ring);
947 kfree(request);
948 }
949}
Chris Wilson54cf91d2010-11-25 18:00:26 +0000950
951static int
952i915_gem_do_execbuffer(struct drm_device *dev, void *data,
953 struct drm_file *file,
954 struct drm_i915_gem_execbuffer2 *args,
Chris Wilson432e58e2010-11-25 19:32:06 +0000955 struct drm_i915_gem_exec_object2 *exec)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000956{
957 drm_i915_private_t *dev_priv = dev->dev_private;
Chris Wilson432e58e2010-11-25 19:32:06 +0000958 struct list_head objects;
Chris Wilson67731b82010-12-08 10:38:14 +0000959 struct eb_objects *eb;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000960 struct drm_i915_gem_object *batch_obj;
961 struct drm_clip_rect *cliprects = NULL;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000962 struct intel_ring_buffer *ring;
Chris Wilsonc4e7a412010-11-30 14:10:25 +0000963 u32 exec_start, exec_len;
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000964 u32 seqno;
Chris Wilson72bfa192010-12-19 11:42:05 +0000965 int ret, mode, i;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000966
Chris Wilson432e58e2010-11-25 19:32:06 +0000967 if (!i915_gem_check_execbuffer(args)) {
968 DRM_ERROR("execbuf with invalid offset/length\n");
969 return -EINVAL;
970 }
971
972 ret = validate_exec_list(exec, args->buffer_count);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000973 if (ret)
974 return ret;
975
976#if WATCH_EXEC
977 DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
978 (int) args->buffers_ptr, args->buffer_count, args->batch_len);
979#endif
980 switch (args->flags & I915_EXEC_RING_MASK) {
981 case I915_EXEC_DEFAULT:
982 case I915_EXEC_RENDER:
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000983 ring = &dev_priv->ring[RCS];
Chris Wilson54cf91d2010-11-25 18:00:26 +0000984 break;
985 case I915_EXEC_BSD:
986 if (!HAS_BSD(dev)) {
987 DRM_ERROR("execbuf with invalid ring (BSD)\n");
988 return -EINVAL;
989 }
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000990 ring = &dev_priv->ring[VCS];
Chris Wilson54cf91d2010-11-25 18:00:26 +0000991 break;
992 case I915_EXEC_BLT:
993 if (!HAS_BLT(dev)) {
994 DRM_ERROR("execbuf with invalid ring (BLT)\n");
995 return -EINVAL;
996 }
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000997 ring = &dev_priv->ring[BCS];
Chris Wilson54cf91d2010-11-25 18:00:26 +0000998 break;
999 default:
1000 DRM_ERROR("execbuf with unknown ring: %d\n",
1001 (int)(args->flags & I915_EXEC_RING_MASK));
1002 return -EINVAL;
1003 }
1004
Chris Wilson72bfa192010-12-19 11:42:05 +00001005 mode = args->flags & I915_EXEC_CONSTANTS_MASK;
1006 switch (mode) {
1007 case I915_EXEC_CONSTANTS_REL_GENERAL:
1008 case I915_EXEC_CONSTANTS_ABSOLUTE:
1009 case I915_EXEC_CONSTANTS_REL_SURFACE:
1010 if (ring == &dev_priv->ring[RCS] &&
1011 mode != dev_priv->relative_constants_mode) {
1012 if (INTEL_INFO(dev)->gen < 4)
1013 return -EINVAL;
1014
1015 if (INTEL_INFO(dev)->gen > 5 &&
1016 mode == I915_EXEC_CONSTANTS_REL_SURFACE)
1017 return -EINVAL;
1018
1019 ret = intel_ring_begin(ring, 4);
1020 if (ret)
1021 return ret;
1022
1023 intel_ring_emit(ring, MI_NOOP);
1024 intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
1025 intel_ring_emit(ring, INSTPM);
1026 intel_ring_emit(ring,
1027 I915_EXEC_CONSTANTS_MASK << 16 | mode);
1028 intel_ring_advance(ring);
1029
1030 dev_priv->relative_constants_mode = mode;
1031 }
1032 break;
1033 default:
1034 DRM_ERROR("execbuf with unknown constants: %d\n", mode);
1035 return -EINVAL;
1036 }
1037
Chris Wilson54cf91d2010-11-25 18:00:26 +00001038 if (args->buffer_count < 1) {
1039 DRM_ERROR("execbuf with %d buffers\n", args->buffer_count);
1040 return -EINVAL;
1041 }
Chris Wilson54cf91d2010-11-25 18:00:26 +00001042
1043 if (args->num_cliprects != 0) {
Chris Wilson1ec14ad2010-12-04 11:30:53 +00001044 if (ring != &dev_priv->ring[RCS]) {
Chris Wilsonc4e7a412010-11-30 14:10:25 +00001045 DRM_ERROR("clip rectangles are only valid with the render ring\n");
1046 return -EINVAL;
1047 }
1048
Chris Wilson432e58e2010-11-25 19:32:06 +00001049 cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects),
Chris Wilson54cf91d2010-11-25 18:00:26 +00001050 GFP_KERNEL);
1051 if (cliprects == NULL) {
1052 ret = -ENOMEM;
1053 goto pre_mutex_err;
1054 }
1055
Chris Wilson432e58e2010-11-25 19:32:06 +00001056 if (copy_from_user(cliprects,
1057 (struct drm_clip_rect __user *)(uintptr_t)
1058 args->cliprects_ptr,
1059 sizeof(*cliprects)*args->num_cliprects)) {
Chris Wilson54cf91d2010-11-25 18:00:26 +00001060 ret = -EFAULT;
1061 goto pre_mutex_err;
1062 }
1063 }
1064
Chris Wilson54cf91d2010-11-25 18:00:26 +00001065 ret = i915_mutex_lock_interruptible(dev);
1066 if (ret)
1067 goto pre_mutex_err;
1068
1069 if (dev_priv->mm.suspended) {
1070 mutex_unlock(&dev->struct_mutex);
1071 ret = -EBUSY;
1072 goto pre_mutex_err;
1073 }
1074
Chris Wilson67731b82010-12-08 10:38:14 +00001075 eb = eb_create(args->buffer_count);
1076 if (eb == NULL) {
1077 mutex_unlock(&dev->struct_mutex);
1078 ret = -ENOMEM;
1079 goto pre_mutex_err;
1080 }
1081
Chris Wilson54cf91d2010-11-25 18:00:26 +00001082 /* Look up object handles */
Chris Wilson432e58e2010-11-25 19:32:06 +00001083 INIT_LIST_HEAD(&objects);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001084 for (i = 0; i < args->buffer_count; i++) {
1085 struct drm_i915_gem_object *obj;
1086
Chris Wilson432e58e2010-11-25 19:32:06 +00001087 obj = to_intel_bo(drm_gem_object_lookup(dev, file,
1088 exec[i].handle));
Chris Wilson54cf91d2010-11-25 18:00:26 +00001089 if (obj == NULL) {
1090 DRM_ERROR("Invalid object handle %d at index %d\n",
Chris Wilson432e58e2010-11-25 19:32:06 +00001091 exec[i].handle, i);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001092 /* prevent error path from reading uninitialized data */
Chris Wilson54cf91d2010-11-25 18:00:26 +00001093 ret = -ENOENT;
1094 goto err;
1095 }
Chris Wilson54cf91d2010-11-25 18:00:26 +00001096
Chris Wilson432e58e2010-11-25 19:32:06 +00001097 if (!list_empty(&obj->exec_list)) {
1098 DRM_ERROR("Object %p [handle %d, index %d] appears more than once in object list\n",
1099 obj, exec[i].handle, i);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001100 ret = -EINVAL;
1101 goto err;
1102 }
Chris Wilson432e58e2010-11-25 19:32:06 +00001103
1104 list_add_tail(&obj->exec_list, &objects);
Chris Wilson67731b82010-12-08 10:38:14 +00001105 obj->exec_handle = exec[i].handle;
1106 eb_add_object(eb, obj);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001107 }
1108
1109 /* Move the objects en-masse into the GTT, evicting if necessary. */
Chris Wilsond9e86c02010-11-10 16:40:20 +00001110 ret = i915_gem_execbuffer_reserve(ring, file, &objects, exec);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001111 if (ret)
1112 goto err;
1113
1114 /* The objects are in their final locations, apply the relocations. */
Chris Wilson67731b82010-12-08 10:38:14 +00001115 ret = i915_gem_execbuffer_relocate(dev, eb, &objects, exec);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001116 if (ret) {
1117 if (ret == -EFAULT) {
Chris Wilsond9e86c02010-11-10 16:40:20 +00001118 ret = i915_gem_execbuffer_relocate_slow(dev, file, ring,
Chris Wilson67731b82010-12-08 10:38:14 +00001119 &objects, eb,
1120 exec,
Chris Wilson54cf91d2010-11-25 18:00:26 +00001121 args->buffer_count);
1122 BUG_ON(!mutex_is_locked(&dev->struct_mutex));
1123 }
1124 if (ret)
1125 goto err;
1126 }
1127
1128 /* Set the pending read domains for the batch buffer to COMMAND */
Chris Wilson432e58e2010-11-25 19:32:06 +00001129 batch_obj = list_entry(objects.prev,
1130 struct drm_i915_gem_object,
1131 exec_list);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001132 if (batch_obj->base.pending_write_domain) {
1133 DRM_ERROR("Attempting to use self-modifying batch buffer\n");
1134 ret = -EINVAL;
1135 goto err;
1136 }
1137 batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND;
1138
Chris Wilson432e58e2010-11-25 19:32:06 +00001139 ret = i915_gem_execbuffer_move_to_gpu(ring, &objects);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001140 if (ret)
1141 goto err;
1142
Chris Wilson432e58e2010-11-25 19:32:06 +00001143 ret = i915_gem_execbuffer_wait_for_flips(ring, &objects);
1144 if (ret)
Chris Wilson54cf91d2010-11-25 18:00:26 +00001145 goto err;
Chris Wilson54cf91d2010-11-25 18:00:26 +00001146
Chris Wilson1ec14ad2010-12-04 11:30:53 +00001147 seqno = i915_gem_next_request_seqno(dev, ring);
1148 for (i = 0; i < I915_NUM_RINGS-1; i++) {
1149 if (seqno < ring->sync_seqno[i]) {
1150 /* The GPU can not handle its semaphore value wrapping,
1151 * so every billion or so execbuffers, we need to stall
1152 * the GPU in order to reset the counters.
1153 */
1154 ret = i915_gpu_idle(dev);
1155 if (ret)
1156 goto err;
1157
1158 BUG_ON(ring->sync_seqno[i]);
1159 }
1160 }
1161
Chris Wilsonc4e7a412010-11-30 14:10:25 +00001162 exec_start = batch_obj->gtt_offset + args->batch_start_offset;
1163 exec_len = args->batch_len;
1164 if (cliprects) {
1165 for (i = 0; i < args->num_cliprects; i++) {
1166 ret = i915_emit_box(dev, &cliprects[i],
1167 args->DR1, args->DR4);
1168 if (ret)
1169 goto err;
1170
1171 ret = ring->dispatch_execbuffer(ring,
1172 exec_start, exec_len);
1173 if (ret)
1174 goto err;
1175 }
1176 } else {
1177 ret = ring->dispatch_execbuffer(ring, exec_start, exec_len);
1178 if (ret)
1179 goto err;
1180 }
Chris Wilson54cf91d2010-11-25 18:00:26 +00001181
Chris Wilson1ec14ad2010-12-04 11:30:53 +00001182 i915_gem_execbuffer_move_to_active(&objects, ring, seqno);
Chris Wilson432e58e2010-11-25 19:32:06 +00001183 i915_gem_execbuffer_retire_commands(dev, file, ring);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001184
1185err:
Chris Wilson67731b82010-12-08 10:38:14 +00001186 eb_destroy(eb);
Chris Wilson432e58e2010-11-25 19:32:06 +00001187 while (!list_empty(&objects)) {
1188 struct drm_i915_gem_object *obj;
1189
1190 obj = list_first_entry(&objects,
1191 struct drm_i915_gem_object,
1192 exec_list);
1193 list_del_init(&obj->exec_list);
1194 drm_gem_object_unreference(&obj->base);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001195 }
1196
1197 mutex_unlock(&dev->struct_mutex);
1198
1199pre_mutex_err:
Chris Wilson54cf91d2010-11-25 18:00:26 +00001200 kfree(cliprects);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001201 return ret;
1202}
1203
1204/*
1205 * Legacy execbuffer just creates an exec2 list from the original exec object
1206 * list array and passes it to the real function.
1207 */
1208int
1209i915_gem_execbuffer(struct drm_device *dev, void *data,
1210 struct drm_file *file)
1211{
1212 struct drm_i915_gem_execbuffer *args = data;
1213 struct drm_i915_gem_execbuffer2 exec2;
1214 struct drm_i915_gem_exec_object *exec_list = NULL;
1215 struct drm_i915_gem_exec_object2 *exec2_list = NULL;
1216 int ret, i;
1217
1218#if WATCH_EXEC
1219 DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
1220 (int) args->buffers_ptr, args->buffer_count, args->batch_len);
1221#endif
1222
1223 if (args->buffer_count < 1) {
1224 DRM_ERROR("execbuf with %d buffers\n", args->buffer_count);
1225 return -EINVAL;
1226 }
1227
1228 /* Copy in the exec list from userland */
1229 exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count);
1230 exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count);
1231 if (exec_list == NULL || exec2_list == NULL) {
1232 DRM_ERROR("Failed to allocate exec list for %d buffers\n",
1233 args->buffer_count);
1234 drm_free_large(exec_list);
1235 drm_free_large(exec2_list);
1236 return -ENOMEM;
1237 }
1238 ret = copy_from_user(exec_list,
1239 (struct drm_i915_relocation_entry __user *)
1240 (uintptr_t) args->buffers_ptr,
1241 sizeof(*exec_list) * args->buffer_count);
1242 if (ret != 0) {
1243 DRM_ERROR("copy %d exec entries failed %d\n",
1244 args->buffer_count, ret);
1245 drm_free_large(exec_list);
1246 drm_free_large(exec2_list);
1247 return -EFAULT;
1248 }
1249
1250 for (i = 0; i < args->buffer_count; i++) {
1251 exec2_list[i].handle = exec_list[i].handle;
1252 exec2_list[i].relocation_count = exec_list[i].relocation_count;
1253 exec2_list[i].relocs_ptr = exec_list[i].relocs_ptr;
1254 exec2_list[i].alignment = exec_list[i].alignment;
1255 exec2_list[i].offset = exec_list[i].offset;
1256 if (INTEL_INFO(dev)->gen < 4)
1257 exec2_list[i].flags = EXEC_OBJECT_NEEDS_FENCE;
1258 else
1259 exec2_list[i].flags = 0;
1260 }
1261
1262 exec2.buffers_ptr = args->buffers_ptr;
1263 exec2.buffer_count = args->buffer_count;
1264 exec2.batch_start_offset = args->batch_start_offset;
1265 exec2.batch_len = args->batch_len;
1266 exec2.DR1 = args->DR1;
1267 exec2.DR4 = args->DR4;
1268 exec2.num_cliprects = args->num_cliprects;
1269 exec2.cliprects_ptr = args->cliprects_ptr;
1270 exec2.flags = I915_EXEC_RENDER;
1271
1272 ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list);
1273 if (!ret) {
1274 /* Copy the new buffer offsets back to the user's exec list. */
1275 for (i = 0; i < args->buffer_count; i++)
1276 exec_list[i].offset = exec2_list[i].offset;
1277 /* ... and back out to userspace */
1278 ret = copy_to_user((struct drm_i915_relocation_entry __user *)
1279 (uintptr_t) args->buffers_ptr,
1280 exec_list,
1281 sizeof(*exec_list) * args->buffer_count);
1282 if (ret) {
1283 ret = -EFAULT;
1284 DRM_ERROR("failed to copy %d exec entries "
1285 "back to user (%d)\n",
1286 args->buffer_count, ret);
1287 }
1288 }
1289
1290 drm_free_large(exec_list);
1291 drm_free_large(exec2_list);
1292 return ret;
1293}
1294
1295int
1296i915_gem_execbuffer2(struct drm_device *dev, void *data,
1297 struct drm_file *file)
1298{
1299 struct drm_i915_gem_execbuffer2 *args = data;
1300 struct drm_i915_gem_exec_object2 *exec2_list = NULL;
1301 int ret;
1302
1303#if WATCH_EXEC
1304 DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
1305 (int) args->buffers_ptr, args->buffer_count, args->batch_len);
1306#endif
1307
1308 if (args->buffer_count < 1) {
1309 DRM_ERROR("execbuf2 with %d buffers\n", args->buffer_count);
1310 return -EINVAL;
1311 }
1312
1313 exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count);
1314 if (exec2_list == NULL) {
1315 DRM_ERROR("Failed to allocate exec list for %d buffers\n",
1316 args->buffer_count);
1317 return -ENOMEM;
1318 }
1319 ret = copy_from_user(exec2_list,
1320 (struct drm_i915_relocation_entry __user *)
1321 (uintptr_t) args->buffers_ptr,
1322 sizeof(*exec2_list) * args->buffer_count);
1323 if (ret != 0) {
1324 DRM_ERROR("copy %d exec entries failed %d\n",
1325 args->buffer_count, ret);
1326 drm_free_large(exec2_list);
1327 return -EFAULT;
1328 }
1329
1330 ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list);
1331 if (!ret) {
1332 /* Copy the new buffer offsets back to the user's exec list. */
1333 ret = copy_to_user((struct drm_i915_relocation_entry __user *)
1334 (uintptr_t) args->buffers_ptr,
1335 exec2_list,
1336 sizeof(*exec2_list) * args->buffer_count);
1337 if (ret) {
1338 ret = -EFAULT;
1339 DRM_ERROR("failed to copy %d exec entries "
1340 "back to user (%d)\n",
1341 args->buffer_count, ret);
1342 }
1343 }
1344
1345 drm_free_large(exec2_list);
1346 return ret;
1347}
1348