OSDN Git Service

intel: add missing drm_public exports
[android-x86/external-libdrm.git] / intel / intel_bufmgr_fake.c
1 /**************************************************************************
2  * 
3  * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
4  * All Rights Reserved.
5  * 
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  * 
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  * 
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  * 
26  **************************************************************************/
27
28 /* Originally a fake version of the buffer manager so that we can
29  * prototype the changes in a driver fairly quickly, has been fleshed
30  * out to a fully functional interim solution.
31  *
32  * Basically wraps the old style memory management in the new
33  * programming interface, but is more expressive and avoids many of
34  * the bugs in the old texture manager.
35  */
36
37 #include <stdlib.h>
38 #include <string.h>
39 #include <assert.h>
40 #include <errno.h>
41 #include <strings.h>
42 #include <xf86drm.h>
43 #include <pthread.h>
44 #include "intel_bufmgr.h"
45 #include "intel_bufmgr_priv.h"
46 #include "drm.h"
47 #include "i915_drm.h"
48 #include "mm.h"
49 #include "libdrm_macros.h"
50 #include "libdrm_lists.h"
51
52 #define DBG(...) do {                                   \
53         if (bufmgr_fake->bufmgr.debug)                  \
54                 drmMsg(__VA_ARGS__);                    \
55 } while (0)
56
57 /* Internal flags:
58  */
59 #define BM_NO_BACKING_STORE                     0x00000001
60 #define BM_NO_FENCE_SUBDATA                     0x00000002
61 #define BM_PINNED                               0x00000004
62
63 /* Wrapper around mm.c's mem_block, which understands that you must
64  * wait for fences to expire before memory can be freed.  This is
65  * specific to our use of memcpy for uploads - an upload that was
66  * processed through the command queue wouldn't need to care about
67  * fences.
68  */
69 #define MAX_RELOCS 4096
70
71 struct fake_buffer_reloc {
72         /** Buffer object that the relocation points at. */
73         drm_intel_bo *target_buf;
74         /** Offset of the relocation entry within reloc_buf. */
75         uint32_t offset;
76         /**
77          * Cached value of the offset when we last performed this relocation.
78          */
79         uint32_t last_target_offset;
80         /** Value added to target_buf's offset to get the relocation entry. */
81         uint32_t delta;
82         /** Cache domains the target buffer is read into. */
83         uint32_t read_domains;
84         /** Cache domain the target buffer will have dirty cachelines in. */
85         uint32_t write_domain;
86 };
87
88 struct block {
89         struct block *next, *prev;
90         struct mem_block *mem;  /* BM_MEM_AGP */
91
92         /**
93          * Marks that the block is currently in the aperture and has yet to be
94          * fenced.
95          */
96         unsigned on_hardware:1;
97         /**
98          * Marks that the block is currently fenced (being used by rendering)
99          * and can't be freed until @fence is passed.
100          */
101         unsigned fenced:1;
102
103         /** Fence cookie for the block. */
104         unsigned fence;         /* Split to read_fence, write_fence */
105
106         drm_intel_bo *bo;
107         void *virtual;
108 };
109
110 typedef struct _bufmgr_fake {
111         drm_intel_bufmgr bufmgr;
112
113         pthread_mutex_t lock;
114
115         unsigned long low_offset;
116         unsigned long size;
117         void *virtual;
118
119         struct mem_block *heap;
120
121         unsigned buf_nr;        /* for generating ids */
122
123         /**
124          * List of blocks which are currently in the GART but haven't been
125          * fenced yet.
126          */
127         struct block on_hardware;
128         /**
129          * List of blocks which are in the GART and have an active fence on
130          * them.
131          */
132         struct block fenced;
133         /**
134          * List of blocks which have an expired fence and are ready to be
135          * evicted.
136          */
137         struct block lru;
138
139         unsigned int last_fence;
140
141         unsigned fail:1;
142         unsigned need_fence:1;
143         int thrashing;
144
145         /**
146          * Driver callback to emit a fence, returning the cookie.
147          *
148          * This allows the driver to hook in a replacement for the DRM usage in
149          * bufmgr_fake.
150          *
151          * Currently, this also requires that a write flush be emitted before
152          * emitting the fence, but this should change.
153          */
154         unsigned int (*fence_emit) (void *private);
155         /** Driver callback to wait for a fence cookie to have passed. */
156         void (*fence_wait) (unsigned int fence, void *private);
157         void *fence_priv;
158
159         /**
160          * Driver callback to execute a buffer.
161          *
162          * This allows the driver to hook in a replacement for the DRM usage in
163          * bufmgr_fake.
164          */
165         int (*exec) (drm_intel_bo *bo, unsigned int used, void *priv);
166         void *exec_priv;
167
168         /** Driver-supplied argument to driver callbacks */
169         void *driver_priv;
170         /**
171          * Pointer to kernel-updated sarea data for the last completed user irq
172          */
173         volatile int *last_dispatch;
174
175         int fd;
176
177         int debug;
178
179         int performed_rendering;
180 } drm_intel_bufmgr_fake;
181
182 typedef struct _drm_intel_bo_fake {
183         drm_intel_bo bo;
184
185         unsigned id;            /* debug only */
186         const char *name;
187
188         unsigned dirty:1;
189         /**
190          * has the card written to this buffer - we make need to copy it back
191          */
192         unsigned card_dirty:1;
193         unsigned int refcount;
194         /* Flags may consist of any of the DRM_BO flags, plus
195          * DRM_BO_NO_BACKING_STORE and BM_NO_FENCE_SUBDATA, which are the
196          * first two driver private flags.
197          */
198         uint64_t flags;
199         /** Cache domains the target buffer is read into. */
200         uint32_t read_domains;
201         /** Cache domain the target buffer will have dirty cachelines in. */
202         uint32_t write_domain;
203
204         unsigned int alignment;
205         int is_static, validated;
206         unsigned int map_count;
207
208         /** relocation list */
209         struct fake_buffer_reloc *relocs;
210         int nr_relocs;
211         /**
212          * Total size of the target_bos of this buffer.
213          *
214          * Used for estimation in check_aperture.
215          */
216         unsigned int child_size;
217
218         struct block *block;
219         void *backing_store;
220         void (*invalidate_cb) (drm_intel_bo *bo, void *ptr);
221         void *invalidate_ptr;
222 } drm_intel_bo_fake;
223
224 static int clear_fenced(drm_intel_bufmgr_fake *bufmgr_fake,
225                         unsigned int fence_cookie);
226
227 #define MAXFENCE 0x7fffffff
228
229 static int
230 FENCE_LTE(unsigned a, unsigned b)
231 {
232         if (a == b)
233                 return 1;
234
235         if (a < b && b - a < (1 << 24))
236                 return 1;
237
238         if (a > b && MAXFENCE - a + b < (1 << 24))
239                 return 1;
240
241         return 0;
242 }
243
244 drm_public void
245 drm_intel_bufmgr_fake_set_fence_callback(drm_intel_bufmgr *bufmgr,
246                                          unsigned int (*emit) (void *priv),
247                                          void (*wait) (unsigned int fence,
248                                                        void *priv),
249                                          void *priv)
250 {
251         drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
252
253         bufmgr_fake->fence_emit = emit;
254         bufmgr_fake->fence_wait = wait;
255         bufmgr_fake->fence_priv = priv;
256 }
257
258 static unsigned int
259 _fence_emit_internal(drm_intel_bufmgr_fake *bufmgr_fake)
260 {
261         struct drm_i915_irq_emit ie;
262         int ret, seq = 1;
263
264         if (bufmgr_fake->fence_emit != NULL) {
265                 seq = bufmgr_fake->fence_emit(bufmgr_fake->fence_priv);
266                 return seq;
267         }
268
269         ie.irq_seq = &seq;
270         ret = drmCommandWriteRead(bufmgr_fake->fd, DRM_I915_IRQ_EMIT,
271                                   &ie, sizeof(ie));
272         if (ret) {
273                 drmMsg("%s: drm_i915_irq_emit: %d\n", __func__, ret);
274                 abort();
275         }
276
277         DBG("emit 0x%08x\n", seq);
278         return seq;
279 }
280
281 static void
282 _fence_wait_internal(drm_intel_bufmgr_fake *bufmgr_fake, int seq)
283 {
284         struct drm_i915_irq_wait iw;
285         int hw_seq, busy_count = 0;
286         int ret;
287         int kernel_lied;
288
289         if (bufmgr_fake->fence_wait != NULL) {
290                 bufmgr_fake->fence_wait(seq, bufmgr_fake->fence_priv);
291                 clear_fenced(bufmgr_fake, seq);
292                 return;
293         }
294
295         iw.irq_seq = seq;
296
297         DBG("wait 0x%08x\n", iw.irq_seq);
298
299         /* The kernel IRQ_WAIT implementation is all sorts of broken.
300          * 1) It returns 1 to 0x7fffffff instead of using the full 32-bit
301          *    unsigned range.
302          * 2) It returns 0 if hw_seq >= seq, not seq - hw_seq < 0 on the 32-bit
303          *    signed range.
304          * 3) It waits if seq < hw_seq, not seq - hw_seq > 0 on the 32-bit
305          *    signed range.
306          * 4) It returns -EBUSY in 3 seconds even if the hardware is still
307          *    successfully chewing through buffers.
308          *
309          * Assume that in userland we treat sequence numbers as ints, which
310          * makes some of the comparisons convenient, since the sequence
311          * numbers are all positive signed integers.
312          *
313          * From this we get several cases we need to handle.  Here's a timeline.
314          * 0x2   0x7                                    0x7ffffff8   0x7ffffffd
315          *   |    |                                             |    |
316          * ------------------------------------------------------------
317          *
318          * A) Normal wait for hw to catch up
319          * hw_seq seq
320          *   |    |
321          * ------------------------------------------------------------
322          * seq - hw_seq = 5.  If we call IRQ_WAIT, it will wait for hw to
323          * catch up.
324          *
325          * B) Normal wait for a sequence number that's already passed.
326          * seq    hw_seq
327          *   |    |
328          * ------------------------------------------------------------
329          * seq - hw_seq = -5.  If we call IRQ_WAIT, it returns 0 quickly.
330          *
331          * C) Hardware has already wrapped around ahead of us
332          * hw_seq                                                    seq
333          *   |                                                       |
334          * ------------------------------------------------------------
335          * seq - hw_seq = 0x80000000 - 5.  If we called IRQ_WAIT, it would wait
336          * for hw_seq >= seq, which may never occur.  Thus, we want to catch
337          * this in userland and return 0.
338          *
339          * D) We've wrapped around ahead of the hardware.
340          * seq                                                      hw_seq
341          *   |                                                       |
342          * ------------------------------------------------------------
343          * seq - hw_seq = -(0x80000000 - 5).  If we called IRQ_WAIT, it would
344          * return 0 quickly because hw_seq >= seq, even though the hardware
345          * isn't caught up. Thus, we need to catch this early return in
346          * userland and bother the kernel until the hardware really does
347          * catch up.
348          *
349          * E) Hardware might wrap after we test in userland.
350          *                                                  hw_seq  seq
351          *                                                      |    |
352          * ------------------------------------------------------------
353          * seq - hw_seq = 5.  If we call IRQ_WAIT, it will likely see seq >=
354          * hw_seq and wait.  However, suppose hw_seq wraps before we make it
355          * into the kernel.  The kernel sees hw_seq >= seq and waits for 3
356          * seconds then returns -EBUSY.  This is case C).  We should catch
357          * this and then return successfully.
358          *
359          * F) Hardware might take a long time on a buffer.
360          * hw_seq seq
361          *   |    |
362          * -------------------------------------------------------------------
363          * seq - hw_seq = 5.  If we call IRQ_WAIT, if sequence 2 through 5
364          * take too long, it will return -EBUSY.  Batchbuffers in the
365          * gltestperf demo were seen to take up to 7 seconds.  We should
366          * catch early -EBUSY return and keep trying.
367          */
368
369         do {
370                 /* Keep a copy of last_dispatch so that if the wait -EBUSYs
371                  * because the hardware didn't catch up in 3 seconds, we can
372                  * see if it at least made progress and retry.
373                  */
374                 hw_seq = *bufmgr_fake->last_dispatch;
375
376                 /* Catch case C */
377                 if (seq - hw_seq > 0x40000000)
378                         return;
379
380                 ret = drmCommandWrite(bufmgr_fake->fd, DRM_I915_IRQ_WAIT,
381                                       &iw, sizeof(iw));
382                 /* Catch case D */
383                 kernel_lied = (ret == 0) && (seq - *bufmgr_fake->last_dispatch <
384                                              -0x40000000);
385
386                 /* Catch case E */
387                 if (ret == -EBUSY
388                     && (seq - *bufmgr_fake->last_dispatch > 0x40000000))
389                         ret = 0;
390
391                 /* Catch case F: Allow up to 15 seconds chewing on one buffer. */
392                 if ((ret == -EBUSY) && (hw_seq != *bufmgr_fake->last_dispatch))
393                         busy_count = 0;
394                 else
395                         busy_count++;
396         } while (kernel_lied || ret == -EAGAIN || ret == -EINTR ||
397                  (ret == -EBUSY && busy_count < 5));
398
399         if (ret != 0) {
400                 drmMsg("%s:%d: Error waiting for fence: %s.\n", __FILE__,
401                        __LINE__, strerror(-ret));
402                 abort();
403         }
404         clear_fenced(bufmgr_fake, seq);
405 }
406
407 static int
408 _fence_test(drm_intel_bufmgr_fake *bufmgr_fake, unsigned fence)
409 {
410         /* Slight problem with wrap-around:
411          */
412         return fence == 0 || FENCE_LTE(fence, bufmgr_fake->last_fence);
413 }
414
415 /**
416  * Allocate a memory manager block for the buffer.
417  */
418 static int
419 alloc_block(drm_intel_bo *bo)
420 {
421         drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
422         drm_intel_bufmgr_fake *bufmgr_fake =
423             (drm_intel_bufmgr_fake *) bo->bufmgr;
424         struct block *block = (struct block *)calloc(sizeof *block, 1);
425         unsigned int align_log2 = ffs(bo_fake->alignment) - 1;
426         unsigned int sz;
427
428         if (!block)
429                 return 1;
430
431         sz = (bo->size + bo_fake->alignment - 1) & ~(bo_fake->alignment - 1);
432
433         block->mem = mmAllocMem(bufmgr_fake->heap, sz, align_log2, 0);
434         if (!block->mem) {
435                 free(block);
436                 return 0;
437         }
438
439         DRMINITLISTHEAD(block);
440
441         /* Insert at head or at tail??? */
442         DRMLISTADDTAIL(block, &bufmgr_fake->lru);
443
444         block->virtual = (uint8_t *) bufmgr_fake->virtual +
445             block->mem->ofs - bufmgr_fake->low_offset;
446         block->bo = bo;
447
448         bo_fake->block = block;
449
450         return 1;
451 }
452
453 /* Release the card storage associated with buf:
454  */
455 static void
456 free_block(drm_intel_bufmgr_fake *bufmgr_fake, struct block *block,
457            int skip_dirty_copy)
458 {
459         drm_intel_bo_fake *bo_fake;
460         DBG("free block %p %08x %d %d\n", block, block->mem->ofs,
461             block->on_hardware, block->fenced);
462
463         if (!block)
464                 return;
465
466         bo_fake = (drm_intel_bo_fake *) block->bo;
467
468         if (bo_fake->flags & (BM_PINNED | BM_NO_BACKING_STORE))
469                 skip_dirty_copy = 1;
470
471         if (!skip_dirty_copy && (bo_fake->card_dirty == 1)) {
472                 memcpy(bo_fake->backing_store, block->virtual, block->bo->size);
473                 bo_fake->card_dirty = 0;
474                 bo_fake->dirty = 1;
475         }
476
477         if (block->on_hardware) {
478                 block->bo = NULL;
479         } else if (block->fenced) {
480                 block->bo = NULL;
481         } else {
482                 DBG("    - free immediately\n");
483                 DRMLISTDEL(block);
484
485                 mmFreeMem(block->mem);
486                 free(block);
487         }
488 }
489
490 static void
491 alloc_backing_store(drm_intel_bo *bo)
492 {
493         drm_intel_bufmgr_fake *bufmgr_fake =
494             (drm_intel_bufmgr_fake *) bo->bufmgr;
495         drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
496         assert(!bo_fake->backing_store);
497         assert(!(bo_fake->flags & (BM_PINNED | BM_NO_BACKING_STORE)));
498
499         bo_fake->backing_store = malloc(bo->size);
500
501         DBG("alloc_backing - buf %d %p %lu\n", bo_fake->id,
502             bo_fake->backing_store, bo->size);
503         assert(bo_fake->backing_store);
504 }
505
506 static void
507 free_backing_store(drm_intel_bo *bo)
508 {
509         drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
510
511         if (bo_fake->backing_store) {
512                 assert(!(bo_fake->flags & (BM_PINNED | BM_NO_BACKING_STORE)));
513                 free(bo_fake->backing_store);
514                 bo_fake->backing_store = NULL;
515         }
516 }
517
518 static void
519 set_dirty(drm_intel_bo *bo)
520 {
521         drm_intel_bufmgr_fake *bufmgr_fake =
522             (drm_intel_bufmgr_fake *) bo->bufmgr;
523         drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
524
525         if (bo_fake->flags & BM_NO_BACKING_STORE
526             && bo_fake->invalidate_cb != NULL)
527                 bo_fake->invalidate_cb(bo, bo_fake->invalidate_ptr);
528
529         assert(!(bo_fake->flags & BM_PINNED));
530
531         DBG("set_dirty - buf %d\n", bo_fake->id);
532         bo_fake->dirty = 1;
533 }
534
535 static int
536 evict_lru(drm_intel_bufmgr_fake *bufmgr_fake, unsigned int max_fence)
537 {
538         struct block *block, *tmp;
539
540         DBG("%s\n", __func__);
541
542         DRMLISTFOREACHSAFE(block, tmp, &bufmgr_fake->lru) {
543                 drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) block->bo;
544
545                 if (bo_fake != NULL && (bo_fake->flags & BM_NO_FENCE_SUBDATA))
546                         continue;
547
548                 if (block->fence && max_fence && !FENCE_LTE(block->fence,
549                                                             max_fence))
550                         return 0;
551
552                 set_dirty(&bo_fake->bo);
553                 bo_fake->block = NULL;
554
555                 free_block(bufmgr_fake, block, 0);
556                 return 1;
557         }
558
559         return 0;
560 }
561
562 static int
563 evict_mru(drm_intel_bufmgr_fake *bufmgr_fake)
564 {
565         struct block *block, *tmp;
566
567         DBG("%s\n", __func__);
568
569         DRMLISTFOREACHSAFEREVERSE(block, tmp, &bufmgr_fake->lru) {
570                 drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) block->bo;
571
572                 if (bo_fake && (bo_fake->flags & BM_NO_FENCE_SUBDATA))
573                         continue;
574
575                 set_dirty(&bo_fake->bo);
576                 bo_fake->block = NULL;
577
578                 free_block(bufmgr_fake, block, 0);
579                 return 1;
580         }
581
582         return 0;
583 }
584
585 /**
586  * Removes all objects from the fenced list older than the given fence.
587  */
588 static int
589 clear_fenced(drm_intel_bufmgr_fake *bufmgr_fake, unsigned int fence_cookie)
590 {
591         struct block *block, *tmp;
592         int ret = 0;
593
594         bufmgr_fake->last_fence = fence_cookie;
595         DRMLISTFOREACHSAFE(block, tmp, &bufmgr_fake->fenced) {
596                 assert(block->fenced);
597
598                 if (_fence_test(bufmgr_fake, block->fence)) {
599
600                         block->fenced = 0;
601
602                         if (!block->bo) {
603                                 DBG("delayed free: offset %x sz %x\n",
604                                     block->mem->ofs, block->mem->size);
605                                 DRMLISTDEL(block);
606                                 mmFreeMem(block->mem);
607                                 free(block);
608                         } else {
609                                 DBG("return to lru: offset %x sz %x\n",
610                                     block->mem->ofs, block->mem->size);
611                                 DRMLISTDEL(block);
612                                 DRMLISTADDTAIL(block, &bufmgr_fake->lru);
613                         }
614
615                         ret = 1;
616                 } else {
617                         /* Blocks are ordered by fence, so if one fails, all
618                          * from here will fail also:
619                          */
620                         DBG("fence not passed: offset %x sz %x %d %d \n",
621                             block->mem->ofs, block->mem->size, block->fence,
622                             bufmgr_fake->last_fence);
623                         break;
624                 }
625         }
626
627         DBG("%s: %d\n", __func__, ret);
628         return ret;
629 }
630
631 static void
632 fence_blocks(drm_intel_bufmgr_fake *bufmgr_fake, unsigned fence)
633 {
634         struct block *block, *tmp;
635
636         DRMLISTFOREACHSAFE(block, tmp, &bufmgr_fake->on_hardware) {
637                 DBG("Fence block %p (sz 0x%x ofs %x buf %p) with fence %d\n",
638                     block, block->mem->size, block->mem->ofs, block->bo, fence);
639                 block->fence = fence;
640
641                 block->on_hardware = 0;
642                 block->fenced = 1;
643
644                 /* Move to tail of pending list here
645                  */
646                 DRMLISTDEL(block);
647                 DRMLISTADDTAIL(block, &bufmgr_fake->fenced);
648         }
649
650         assert(DRMLISTEMPTY(&bufmgr_fake->on_hardware));
651 }
652
653 static int
654 evict_and_alloc_block(drm_intel_bo *bo)
655 {
656         drm_intel_bufmgr_fake *bufmgr_fake =
657             (drm_intel_bufmgr_fake *) bo->bufmgr;
658         drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
659
660         assert(bo_fake->block == NULL);
661
662         /* Search for already free memory:
663          */
664         if (alloc_block(bo))
665                 return 1;
666
667         /* If we're not thrashing, allow lru eviction to dig deeper into
668          * recently used textures.  We'll probably be thrashing soon:
669          */
670         if (!bufmgr_fake->thrashing) {
671                 while (evict_lru(bufmgr_fake, 0))
672                         if (alloc_block(bo))
673                                 return 1;
674         }
675
676         /* Keep thrashing counter alive?
677          */
678         if (bufmgr_fake->thrashing)
679                 bufmgr_fake->thrashing = 20;
680
681         /* Wait on any already pending fences - here we are waiting for any
682          * freed memory that has been submitted to hardware and fenced to
683          * become available:
684          */
685         while (!DRMLISTEMPTY(&bufmgr_fake->fenced)) {
686                 uint32_t fence = bufmgr_fake->fenced.next->fence;
687                 _fence_wait_internal(bufmgr_fake, fence);
688
689                 if (alloc_block(bo))
690                         return 1;
691         }
692
693         if (!DRMLISTEMPTY(&bufmgr_fake->on_hardware)) {
694                 while (!DRMLISTEMPTY(&bufmgr_fake->fenced)) {
695                         uint32_t fence = bufmgr_fake->fenced.next->fence;
696                         _fence_wait_internal(bufmgr_fake, fence);
697                 }
698
699                 if (!bufmgr_fake->thrashing) {
700                         DBG("thrashing\n");
701                 }
702                 bufmgr_fake->thrashing = 20;
703
704                 if (alloc_block(bo))
705                         return 1;
706         }
707
708         while (evict_mru(bufmgr_fake))
709                 if (alloc_block(bo))
710                         return 1;
711
712         DBG("%s 0x%lx bytes failed\n", __func__, bo->size);
713
714         return 0;
715 }
716
717 /***********************************************************************
718  * Public functions
719  */
720
721 /**
722  * Wait for hardware idle by emitting a fence and waiting for it.
723  */
724 static void
725 drm_intel_bufmgr_fake_wait_idle(drm_intel_bufmgr_fake *bufmgr_fake)
726 {
727         unsigned int cookie;
728
729         cookie = _fence_emit_internal(bufmgr_fake);
730         _fence_wait_internal(bufmgr_fake, cookie);
731 }
732
733 /**
734  * Wait for rendering to a buffer to complete.
735  *
736  * It is assumed that the batchbuffer which performed the rendering included
737  * the necessary flushing.
738  */
739 static void
740 drm_intel_fake_bo_wait_rendering_locked(drm_intel_bo *bo)
741 {
742         drm_intel_bufmgr_fake *bufmgr_fake =
743             (drm_intel_bufmgr_fake *) bo->bufmgr;
744         drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
745
746         if (bo_fake->block == NULL || !bo_fake->block->fenced)
747                 return;
748
749         _fence_wait_internal(bufmgr_fake, bo_fake->block->fence);
750 }
751
752 static void
753 drm_intel_fake_bo_wait_rendering(drm_intel_bo *bo)
754 {
755         drm_intel_bufmgr_fake *bufmgr_fake =
756             (drm_intel_bufmgr_fake *) bo->bufmgr;
757
758         pthread_mutex_lock(&bufmgr_fake->lock);
759         drm_intel_fake_bo_wait_rendering_locked(bo);
760         pthread_mutex_unlock(&bufmgr_fake->lock);
761 }
762
763 /* Specifically ignore texture memory sharing.
764  *  -- just evict everything
765  *  -- and wait for idle
766  */
767 drm_public void
768 drm_intel_bufmgr_fake_contended_lock_take(drm_intel_bufmgr *bufmgr)
769 {
770         drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
771         struct block *block, *tmp;
772
773         pthread_mutex_lock(&bufmgr_fake->lock);
774
775         bufmgr_fake->need_fence = 1;
776         bufmgr_fake->fail = 0;
777
778         /* Wait for hardware idle.  We don't know where acceleration has been
779          * happening, so we'll need to wait anyway before letting anything get
780          * put on the card again.
781          */
782         drm_intel_bufmgr_fake_wait_idle(bufmgr_fake);
783
784         /* Check that we hadn't released the lock without having fenced the last
785          * set of buffers.
786          */
787         assert(DRMLISTEMPTY(&bufmgr_fake->fenced));
788         assert(DRMLISTEMPTY(&bufmgr_fake->on_hardware));
789
790         DRMLISTFOREACHSAFE(block, tmp, &bufmgr_fake->lru) {
791                 assert(_fence_test(bufmgr_fake, block->fence));
792                 set_dirty(block->bo);
793         }
794
795         pthread_mutex_unlock(&bufmgr_fake->lock);
796 }
797
798 static drm_intel_bo *
799 drm_intel_fake_bo_alloc(drm_intel_bufmgr *bufmgr,
800                         const char *name,
801                         unsigned long size,
802                         unsigned int alignment)
803 {
804         drm_intel_bufmgr_fake *bufmgr_fake;
805         drm_intel_bo_fake *bo_fake;
806
807         bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
808
809         assert(size != 0);
810
811         bo_fake = calloc(1, sizeof(*bo_fake));
812         if (!bo_fake)
813                 return NULL;
814
815         bo_fake->bo.size = size;
816         bo_fake->bo.offset = -1;
817         bo_fake->bo.virtual = NULL;
818         bo_fake->bo.bufmgr = bufmgr;
819         bo_fake->refcount = 1;
820
821         /* Alignment must be a power of two */
822         assert((alignment & (alignment - 1)) == 0);
823         if (alignment == 0)
824                 alignment = 1;
825         bo_fake->alignment = alignment;
826         bo_fake->id = ++bufmgr_fake->buf_nr;
827         bo_fake->name = name;
828         bo_fake->flags = 0;
829         bo_fake->is_static = 0;
830
831         DBG("drm_bo_alloc: (buf %d: %s, %lu kb)\n", bo_fake->id, bo_fake->name,
832             bo_fake->bo.size / 1024);
833
834         return &bo_fake->bo;
835 }
836
837 static drm_intel_bo *
838 drm_intel_fake_bo_alloc_tiled(drm_intel_bufmgr * bufmgr,
839                               const char *name,
840                               int x, int y, int cpp,
841                               uint32_t *tiling_mode,
842                               unsigned long *pitch,
843                               unsigned long flags)
844 {
845         unsigned long stride, aligned_y;
846
847         /* No runtime tiling support for fake. */
848         *tiling_mode = I915_TILING_NONE;
849
850         /* Align it for being a render target.  Shouldn't need anything else. */
851         stride = x * cpp;
852         stride = ROUND_UP_TO(stride, 64);
853
854         /* 965 subspan loading alignment */
855         aligned_y = ALIGN(y, 2);
856
857         *pitch = stride;
858
859         return drm_intel_fake_bo_alloc(bufmgr, name, stride * aligned_y,
860                                        4096);
861 }
862
863 drm_public drm_intel_bo *
864 drm_intel_bo_fake_alloc_static(drm_intel_bufmgr *bufmgr,
865                                const char *name,
866                                unsigned long offset,
867                                unsigned long size, void *virtual)
868 {
869         drm_intel_bufmgr_fake *bufmgr_fake;
870         drm_intel_bo_fake *bo_fake;
871
872         bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
873
874         assert(size != 0);
875
876         bo_fake = calloc(1, sizeof(*bo_fake));
877         if (!bo_fake)
878                 return NULL;
879
880         bo_fake->bo.size = size;
881         bo_fake->bo.offset = offset;
882         bo_fake->bo.virtual = virtual;
883         bo_fake->bo.bufmgr = bufmgr;
884         bo_fake->refcount = 1;
885         bo_fake->id = ++bufmgr_fake->buf_nr;
886         bo_fake->name = name;
887         bo_fake->flags = BM_PINNED;
888         bo_fake->is_static = 1;
889
890         DBG("drm_bo_alloc_static: (buf %d: %s, %lu kb)\n", bo_fake->id,
891             bo_fake->name, bo_fake->bo.size / 1024);
892
893         return &bo_fake->bo;
894 }
895
896 static void
897 drm_intel_fake_bo_reference(drm_intel_bo *bo)
898 {
899         drm_intel_bufmgr_fake *bufmgr_fake =
900             (drm_intel_bufmgr_fake *) bo->bufmgr;
901         drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
902
903         pthread_mutex_lock(&bufmgr_fake->lock);
904         bo_fake->refcount++;
905         pthread_mutex_unlock(&bufmgr_fake->lock);
906 }
907
908 static void
909 drm_intel_fake_bo_reference_locked(drm_intel_bo *bo)
910 {
911         drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
912
913         bo_fake->refcount++;
914 }
915
916 static void
917 drm_intel_fake_bo_unreference_locked(drm_intel_bo *bo)
918 {
919         drm_intel_bufmgr_fake *bufmgr_fake =
920             (drm_intel_bufmgr_fake *) bo->bufmgr;
921         drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
922         int i;
923
924         if (--bo_fake->refcount == 0) {
925                 assert(bo_fake->map_count == 0);
926                 /* No remaining references, so free it */
927                 if (bo_fake->block)
928                         free_block(bufmgr_fake, bo_fake->block, 1);
929                 free_backing_store(bo);
930
931                 for (i = 0; i < bo_fake->nr_relocs; i++)
932                         drm_intel_fake_bo_unreference_locked(bo_fake->relocs[i].
933                                                              target_buf);
934
935                 DBG("drm_bo_unreference: free buf %d %s\n", bo_fake->id,
936                     bo_fake->name);
937
938                 free(bo_fake->relocs);
939                 free(bo);
940         }
941 }
942
943 static void
944 drm_intel_fake_bo_unreference(drm_intel_bo *bo)
945 {
946         drm_intel_bufmgr_fake *bufmgr_fake =
947             (drm_intel_bufmgr_fake *) bo->bufmgr;
948
949         pthread_mutex_lock(&bufmgr_fake->lock);
950         drm_intel_fake_bo_unreference_locked(bo);
951         pthread_mutex_unlock(&bufmgr_fake->lock);
952 }
953
954 /**
955  * Set the buffer as not requiring backing store, and instead get the callback
956  * invoked whenever it would be set dirty.
957  */
958 drm_public void
959 drm_intel_bo_fake_disable_backing_store(drm_intel_bo *bo,
960                                         void (*invalidate_cb) (drm_intel_bo *bo,
961                                                                void *ptr),
962                                         void *ptr)
963 {
964         drm_intel_bufmgr_fake *bufmgr_fake =
965             (drm_intel_bufmgr_fake *) bo->bufmgr;
966         drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
967
968         pthread_mutex_lock(&bufmgr_fake->lock);
969
970         if (bo_fake->backing_store)
971                 free_backing_store(bo);
972
973         bo_fake->flags |= BM_NO_BACKING_STORE;
974
975         DBG("disable_backing_store set buf %d dirty\n", bo_fake->id);
976         bo_fake->dirty = 1;
977         bo_fake->invalidate_cb = invalidate_cb;
978         bo_fake->invalidate_ptr = ptr;
979
980         /* Note that it is invalid right from the start.  Also note
981          * invalidate_cb is called with the bufmgr locked, so cannot
982          * itself make bufmgr calls.
983          */
984         if (invalidate_cb != NULL)
985                 invalidate_cb(bo, ptr);
986
987         pthread_mutex_unlock(&bufmgr_fake->lock);
988 }
989
990 /**
991  * Map a buffer into bo->virtual, allocating either card memory space (If
992  * BM_NO_BACKING_STORE or BM_PINNED) or backing store, as necessary.
993  */
994 static int
995  drm_intel_fake_bo_map_locked(drm_intel_bo *bo, int write_enable)
996 {
997         drm_intel_bufmgr_fake *bufmgr_fake =
998             (drm_intel_bufmgr_fake *) bo->bufmgr;
999         drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
1000
1001         /* Static buffers are always mapped. */
1002         if (bo_fake->is_static) {
1003                 if (bo_fake->card_dirty) {
1004                         drm_intel_bufmgr_fake_wait_idle(bufmgr_fake);
1005                         bo_fake->card_dirty = 0;
1006                 }
1007                 return 0;
1008         }
1009
1010         /* Allow recursive mapping.  Mesa may recursively map buffers with
1011          * nested display loops, and it is used internally in bufmgr_fake
1012          * for relocation.
1013          */
1014         if (bo_fake->map_count++ != 0)
1015                 return 0;
1016
1017         {
1018                 DBG("drm_bo_map: (buf %d: %s, %lu kb)\n", bo_fake->id,
1019                     bo_fake->name, bo_fake->bo.size / 1024);
1020
1021                 if (bo->virtual != NULL) {
1022                         drmMsg("%s: already mapped\n", __func__);
1023                         abort();
1024                 } else if (bo_fake->flags & (BM_NO_BACKING_STORE | BM_PINNED)) {
1025
1026                         if (!bo_fake->block && !evict_and_alloc_block(bo)) {
1027                                 DBG("%s: alloc failed\n", __func__);
1028                                 bufmgr_fake->fail = 1;
1029                                 return 1;
1030                         } else {
1031                                 assert(bo_fake->block);
1032                                 bo_fake->dirty = 0;
1033
1034                                 if (!(bo_fake->flags & BM_NO_FENCE_SUBDATA) &&
1035                                     bo_fake->block->fenced) {
1036                                         drm_intel_fake_bo_wait_rendering_locked
1037                                             (bo);
1038                                 }
1039
1040                                 bo->virtual = bo_fake->block->virtual;
1041                         }
1042                 } else {
1043                         if (write_enable)
1044                                 set_dirty(bo);
1045
1046                         if (bo_fake->backing_store == 0)
1047                                 alloc_backing_store(bo);
1048
1049                         if ((bo_fake->card_dirty == 1) && bo_fake->block) {
1050                                 if (bo_fake->block->fenced)
1051                                         drm_intel_fake_bo_wait_rendering_locked
1052                                             (bo);
1053
1054                                 memcpy(bo_fake->backing_store,
1055                                        bo_fake->block->virtual,
1056                                        bo_fake->block->bo->size);
1057                                 bo_fake->card_dirty = 0;
1058                         }
1059
1060                         bo->virtual = bo_fake->backing_store;
1061                 }
1062         }
1063
1064         return 0;
1065 }
1066
1067 static int
1068  drm_intel_fake_bo_map(drm_intel_bo *bo, int write_enable)
1069 {
1070         drm_intel_bufmgr_fake *bufmgr_fake =
1071             (drm_intel_bufmgr_fake *) bo->bufmgr;
1072         int ret;
1073
1074         pthread_mutex_lock(&bufmgr_fake->lock);
1075         ret = drm_intel_fake_bo_map_locked(bo, write_enable);
1076         pthread_mutex_unlock(&bufmgr_fake->lock);
1077
1078         return ret;
1079 }
1080
1081 static int
1082  drm_intel_fake_bo_unmap_locked(drm_intel_bo *bo)
1083 {
1084         drm_intel_bufmgr_fake *bufmgr_fake =
1085             (drm_intel_bufmgr_fake *) bo->bufmgr;
1086         drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
1087
1088         /* Static buffers are always mapped. */
1089         if (bo_fake->is_static)
1090                 return 0;
1091
1092         assert(bo_fake->map_count != 0);
1093         if (--bo_fake->map_count != 0)
1094                 return 0;
1095
1096         DBG("drm_bo_unmap: (buf %d: %s, %lu kb)\n", bo_fake->id, bo_fake->name,
1097             bo_fake->bo.size / 1024);
1098
1099         bo->virtual = NULL;
1100
1101         return 0;
1102 }
1103
1104 static int drm_intel_fake_bo_unmap(drm_intel_bo *bo)
1105 {
1106         drm_intel_bufmgr_fake *bufmgr_fake =
1107             (drm_intel_bufmgr_fake *) bo->bufmgr;
1108         int ret;
1109
1110         pthread_mutex_lock(&bufmgr_fake->lock);
1111         ret = drm_intel_fake_bo_unmap_locked(bo);
1112         pthread_mutex_unlock(&bufmgr_fake->lock);
1113
1114         return ret;
1115 }
1116
1117 static int
1118 drm_intel_fake_bo_subdata(drm_intel_bo *bo, unsigned long offset,
1119                           unsigned long size, const void *data)
1120 {
1121         int ret;
1122
1123         if (size == 0 || data == NULL)
1124                 return 0;
1125
1126         ret = drm_intel_bo_map(bo, 1);
1127         if (ret)
1128                 return ret;
1129         memcpy((unsigned char *)bo->virtual + offset, data, size);
1130         drm_intel_bo_unmap(bo);
1131         return 0;
1132 }
1133
1134 static void
1135  drm_intel_fake_kick_all_locked(drm_intel_bufmgr_fake *bufmgr_fake)
1136 {
1137         struct block *block, *tmp;
1138
1139         bufmgr_fake->performed_rendering = 0;
1140         /* okay for ever BO that is on the HW kick it off.
1141            seriously not afraid of the POLICE right now */
1142         DRMLISTFOREACHSAFE(block, tmp, &bufmgr_fake->on_hardware) {
1143                 drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) block->bo;
1144
1145                 block->on_hardware = 0;
1146                 free_block(bufmgr_fake, block, 0);
1147                 bo_fake->block = NULL;
1148                 bo_fake->validated = 0;
1149                 if (!(bo_fake->flags & BM_NO_BACKING_STORE))
1150                         bo_fake->dirty = 1;
1151         }
1152
1153 }
1154
1155 static int
1156  drm_intel_fake_bo_validate(drm_intel_bo *bo)
1157 {
1158         drm_intel_bufmgr_fake *bufmgr_fake;
1159         drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
1160
1161         bufmgr_fake = (drm_intel_bufmgr_fake *) bo->bufmgr;
1162
1163         DBG("drm_bo_validate: (buf %d: %s, %lu kb)\n", bo_fake->id,
1164             bo_fake->name, bo_fake->bo.size / 1024);
1165
1166         /* Sanity check: Buffers should be unmapped before being validated.
1167          * This is not so much of a problem for bufmgr_fake, but TTM refuses,
1168          * and the problem is harder to debug there.
1169          */
1170         assert(bo_fake->map_count == 0);
1171
1172         if (bo_fake->is_static) {
1173                 /* Add it to the needs-fence list */
1174                 bufmgr_fake->need_fence = 1;
1175                 return 0;
1176         }
1177
1178         /* Allocate the card memory */
1179         if (!bo_fake->block && !evict_and_alloc_block(bo)) {
1180                 bufmgr_fake->fail = 1;
1181                 DBG("Failed to validate buf %d:%s\n", bo_fake->id,
1182                     bo_fake->name);
1183                 return -1;
1184         }
1185
1186         assert(bo_fake->block);
1187         assert(bo_fake->block->bo == &bo_fake->bo);
1188
1189         bo->offset = bo_fake->block->mem->ofs;
1190
1191         /* Upload the buffer contents if necessary */
1192         if (bo_fake->dirty) {
1193                 DBG("Upload dirty buf %d:%s, sz %lu offset 0x%x\n", bo_fake->id,
1194                     bo_fake->name, bo->size, bo_fake->block->mem->ofs);
1195
1196                 assert(!(bo_fake->flags & (BM_NO_BACKING_STORE | BM_PINNED)));
1197
1198                 /* Actually, should be able to just wait for a fence on the
1199                  * memory, which we would be tracking when we free it. Waiting
1200                  * for idle is a sufficiently large hammer for now.
1201                  */
1202                 drm_intel_bufmgr_fake_wait_idle(bufmgr_fake);
1203
1204                 /* we may never have mapped this BO so it might not have any
1205                  * backing store if this happens it should be rare, but 0 the
1206                  * card memory in any case */
1207                 if (bo_fake->backing_store)
1208                         memcpy(bo_fake->block->virtual, bo_fake->backing_store,
1209                                bo->size);
1210                 else
1211                         memset(bo_fake->block->virtual, 0, bo->size);
1212
1213                 bo_fake->dirty = 0;
1214         }
1215
1216         bo_fake->block->fenced = 0;
1217         bo_fake->block->on_hardware = 1;
1218         DRMLISTDEL(bo_fake->block);
1219         DRMLISTADDTAIL(bo_fake->block, &bufmgr_fake->on_hardware);
1220
1221         bo_fake->validated = 1;
1222         bufmgr_fake->need_fence = 1;
1223
1224         return 0;
1225 }
1226
1227 static void
1228 drm_intel_fake_fence_validated(drm_intel_bufmgr *bufmgr)
1229 {
1230         drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
1231         unsigned int cookie;
1232
1233         cookie = _fence_emit_internal(bufmgr_fake);
1234         fence_blocks(bufmgr_fake, cookie);
1235
1236         DBG("drm_fence_validated: 0x%08x cookie\n", cookie);
1237 }
1238
1239 static void
1240 drm_intel_fake_destroy(drm_intel_bufmgr *bufmgr)
1241 {
1242         drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
1243
1244         pthread_mutex_destroy(&bufmgr_fake->lock);
1245         mmDestroy(bufmgr_fake->heap);
1246         free(bufmgr);
1247 }
1248
1249 static int
1250 drm_intel_fake_emit_reloc(drm_intel_bo *bo, uint32_t offset,
1251                           drm_intel_bo *target_bo, uint32_t target_offset,
1252                           uint32_t read_domains, uint32_t write_domain)
1253 {
1254         drm_intel_bufmgr_fake *bufmgr_fake =
1255             (drm_intel_bufmgr_fake *) bo->bufmgr;
1256         struct fake_buffer_reloc *r;
1257         drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
1258         drm_intel_bo_fake *target_fake = (drm_intel_bo_fake *) target_bo;
1259         int i;
1260
1261         pthread_mutex_lock(&bufmgr_fake->lock);
1262
1263         assert(bo);
1264         assert(target_bo);
1265
1266         if (bo_fake->relocs == NULL) {
1267                 bo_fake->relocs =
1268                     malloc(sizeof(struct fake_buffer_reloc) * MAX_RELOCS);
1269         }
1270
1271         r = &bo_fake->relocs[bo_fake->nr_relocs++];
1272
1273         assert(bo_fake->nr_relocs <= MAX_RELOCS);
1274
1275         drm_intel_fake_bo_reference_locked(target_bo);
1276
1277         if (!target_fake->is_static) {
1278                 bo_fake->child_size +=
1279                     ALIGN(target_bo->size, target_fake->alignment);
1280                 bo_fake->child_size += target_fake->child_size;
1281         }
1282         r->target_buf = target_bo;
1283         r->offset = offset;
1284         r->last_target_offset = target_bo->offset;
1285         r->delta = target_offset;
1286         r->read_domains = read_domains;
1287         r->write_domain = write_domain;
1288
1289         if (bufmgr_fake->debug) {
1290                 /* Check that a conflicting relocation hasn't already been
1291                  * emitted.
1292                  */
1293                 for (i = 0; i < bo_fake->nr_relocs - 1; i++) {
1294                         struct fake_buffer_reloc *r2 = &bo_fake->relocs[i];
1295
1296                         assert(r->offset != r2->offset);
1297                 }
1298         }
1299
1300         pthread_mutex_unlock(&bufmgr_fake->lock);
1301
1302         return 0;
1303 }
1304
1305 /**
1306  * Incorporates the validation flags associated with each relocation into
1307  * the combined validation flags for the buffer on this batchbuffer submission.
1308  */
1309 static void
1310 drm_intel_fake_calculate_domains(drm_intel_bo *bo)
1311 {
1312         drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
1313         int i;
1314
1315         for (i = 0; i < bo_fake->nr_relocs; i++) {
1316                 struct fake_buffer_reloc *r = &bo_fake->relocs[i];
1317                 drm_intel_bo_fake *target_fake =
1318                     (drm_intel_bo_fake *) r->target_buf;
1319
1320                 /* Do the same for the tree of buffers we depend on */
1321                 drm_intel_fake_calculate_domains(r->target_buf);
1322
1323                 target_fake->read_domains |= r->read_domains;
1324                 target_fake->write_domain |= r->write_domain;
1325         }
1326 }
1327
1328 static int
1329 drm_intel_fake_reloc_and_validate_buffer(drm_intel_bo *bo)
1330 {
1331         drm_intel_bufmgr_fake *bufmgr_fake =
1332             (drm_intel_bufmgr_fake *) bo->bufmgr;
1333         drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
1334         int i, ret;
1335
1336         assert(bo_fake->map_count == 0);
1337
1338         for (i = 0; i < bo_fake->nr_relocs; i++) {
1339                 struct fake_buffer_reloc *r = &bo_fake->relocs[i];
1340                 drm_intel_bo_fake *target_fake =
1341                     (drm_intel_bo_fake *) r->target_buf;
1342                 uint32_t reloc_data;
1343
1344                 /* Validate the target buffer if that hasn't been done. */
1345                 if (!target_fake->validated) {
1346                         ret =
1347                             drm_intel_fake_reloc_and_validate_buffer(r->target_buf);
1348                         if (ret != 0) {
1349                                 if (bo->virtual != NULL)
1350                                         drm_intel_fake_bo_unmap_locked(bo);
1351                                 return ret;
1352                         }
1353                 }
1354
1355                 /* Calculate the value of the relocation entry. */
1356                 if (r->target_buf->offset != r->last_target_offset) {
1357                         reloc_data = r->target_buf->offset + r->delta;
1358
1359                         if (bo->virtual == NULL)
1360                                 drm_intel_fake_bo_map_locked(bo, 1);
1361
1362                         *(uint32_t *) ((uint8_t *) bo->virtual + r->offset) =
1363                             reloc_data;
1364
1365                         r->last_target_offset = r->target_buf->offset;
1366                 }
1367         }
1368
1369         if (bo->virtual != NULL)
1370                 drm_intel_fake_bo_unmap_locked(bo);
1371
1372         if (bo_fake->write_domain != 0) {
1373                 if (!(bo_fake->flags & (BM_NO_BACKING_STORE | BM_PINNED))) {
1374                         if (bo_fake->backing_store == 0)
1375                                 alloc_backing_store(bo);
1376                 }
1377                 bo_fake->card_dirty = 1;
1378                 bufmgr_fake->performed_rendering = 1;
1379         }
1380
1381         return drm_intel_fake_bo_validate(bo);
1382 }
1383
1384 static void
1385 drm_intel_bo_fake_post_submit(drm_intel_bo *bo)
1386 {
1387         drm_intel_bufmgr_fake *bufmgr_fake =
1388             (drm_intel_bufmgr_fake *) bo->bufmgr;
1389         drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo;
1390         int i;
1391
1392         for (i = 0; i < bo_fake->nr_relocs; i++) {
1393                 struct fake_buffer_reloc *r = &bo_fake->relocs[i];
1394                 drm_intel_bo_fake *target_fake =
1395                     (drm_intel_bo_fake *) r->target_buf;
1396
1397                 if (target_fake->validated)
1398                         drm_intel_bo_fake_post_submit(r->target_buf);
1399
1400                 DBG("%s@0x%08x + 0x%08x -> %s@0x%08x + 0x%08x\n",
1401                     bo_fake->name, (uint32_t) bo->offset, r->offset,
1402                     target_fake->name, (uint32_t) r->target_buf->offset,
1403                     r->delta);
1404         }
1405
1406         assert(bo_fake->map_count == 0);
1407         bo_fake->validated = 0;
1408         bo_fake->read_domains = 0;
1409         bo_fake->write_domain = 0;
1410 }
1411
1412 drm_public void
1413 drm_intel_bufmgr_fake_set_exec_callback(drm_intel_bufmgr *bufmgr,
1414                                              int (*exec) (drm_intel_bo *bo,
1415                                                           unsigned int used,
1416                                                           void *priv),
1417                                              void *priv)
1418 {
1419         drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
1420
1421         bufmgr_fake->exec = exec;
1422         bufmgr_fake->exec_priv = priv;
1423 }
1424
1425 static int
1426 drm_intel_fake_bo_exec(drm_intel_bo *bo, int used,
1427                        drm_clip_rect_t * cliprects, int num_cliprects, int DR4)
1428 {
1429         drm_intel_bufmgr_fake *bufmgr_fake =
1430             (drm_intel_bufmgr_fake *) bo->bufmgr;
1431         drm_intel_bo_fake *batch_fake = (drm_intel_bo_fake *) bo;
1432         struct drm_i915_batchbuffer batch;
1433         int ret;
1434         int retry_count = 0;
1435
1436         pthread_mutex_lock(&bufmgr_fake->lock);
1437
1438         bufmgr_fake->performed_rendering = 0;
1439
1440         drm_intel_fake_calculate_domains(bo);
1441
1442         batch_fake->read_domains = I915_GEM_DOMAIN_COMMAND;
1443
1444         /* we've ran out of RAM so blow the whole lot away and retry */
1445 restart:
1446         ret = drm_intel_fake_reloc_and_validate_buffer(bo);
1447         if (bufmgr_fake->fail == 1) {
1448                 if (retry_count == 0) {
1449                         retry_count++;
1450                         drm_intel_fake_kick_all_locked(bufmgr_fake);
1451                         bufmgr_fake->fail = 0;
1452                         goto restart;
1453                 } else          /* dump out the memory here */
1454                         mmDumpMemInfo(bufmgr_fake->heap);
1455         }
1456
1457         assert(ret == 0);
1458
1459         if (bufmgr_fake->exec != NULL) {
1460                 ret = bufmgr_fake->exec(bo, used, bufmgr_fake->exec_priv);
1461                 if (ret != 0) {
1462                         pthread_mutex_unlock(&bufmgr_fake->lock);
1463                         return ret;
1464                 }
1465         } else {
1466                 batch.start = bo->offset;
1467                 batch.used = used;
1468                 batch.cliprects = cliprects;
1469                 batch.num_cliprects = num_cliprects;
1470                 batch.DR1 = 0;
1471                 batch.DR4 = DR4;
1472
1473                 if (drmCommandWrite
1474                     (bufmgr_fake->fd, DRM_I915_BATCHBUFFER, &batch,
1475                      sizeof(batch))) {
1476                         drmMsg("DRM_I915_BATCHBUFFER: %d\n", -errno);
1477                         pthread_mutex_unlock(&bufmgr_fake->lock);
1478                         return -errno;
1479                 }
1480         }
1481
1482         drm_intel_fake_fence_validated(bo->bufmgr);
1483
1484         drm_intel_bo_fake_post_submit(bo);
1485
1486         pthread_mutex_unlock(&bufmgr_fake->lock);
1487
1488         return 0;
1489 }
1490
1491 /**
1492  * Return an error if the list of BOs will exceed the aperture size.
1493  *
1494  * This is a rough guess and likely to fail, as during the validate sequence we
1495  * may place a buffer in an inopportune spot early on and then fail to fit
1496  * a set smaller than the aperture.
1497  */
1498 static int
1499 drm_intel_fake_check_aperture_space(drm_intel_bo ** bo_array, int count)
1500 {
1501         drm_intel_bufmgr_fake *bufmgr_fake =
1502             (drm_intel_bufmgr_fake *) bo_array[0]->bufmgr;
1503         unsigned int sz = 0;
1504         int i;
1505
1506         for (i = 0; i < count; i++) {
1507                 drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) bo_array[i];
1508
1509                 if (bo_fake == NULL)
1510                         continue;
1511
1512                 if (!bo_fake->is_static)
1513                         sz += ALIGN(bo_array[i]->size, bo_fake->alignment);
1514                 sz += bo_fake->child_size;
1515         }
1516
1517         if (sz > bufmgr_fake->size) {
1518                 DBG("check_space: overflowed bufmgr size, %ukb vs %lukb\n",
1519                     sz / 1024, bufmgr_fake->size / 1024);
1520                 return -1;
1521         }
1522
1523         DBG("drm_check_space: sz %ukb vs bufgr %lukb\n", sz / 1024,
1524             bufmgr_fake->size / 1024);
1525         return 0;
1526 }
1527
1528 /**
1529  * Evicts all buffers, waiting for fences to pass and copying contents out
1530  * as necessary.
1531  *
1532  * Used by the X Server on LeaveVT, when the card memory is no longer our
1533  * own.
1534  */
1535 drm_public void
1536 drm_intel_bufmgr_fake_evict_all(drm_intel_bufmgr *bufmgr)
1537 {
1538         drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
1539         struct block *block, *tmp;
1540
1541         pthread_mutex_lock(&bufmgr_fake->lock);
1542
1543         bufmgr_fake->need_fence = 1;
1544         bufmgr_fake->fail = 0;
1545
1546         /* Wait for hardware idle.  We don't know where acceleration has been
1547          * happening, so we'll need to wait anyway before letting anything get
1548          * put on the card again.
1549          */
1550         drm_intel_bufmgr_fake_wait_idle(bufmgr_fake);
1551
1552         /* Check that we hadn't released the lock without having fenced the last
1553          * set of buffers.
1554          */
1555         assert(DRMLISTEMPTY(&bufmgr_fake->fenced));
1556         assert(DRMLISTEMPTY(&bufmgr_fake->on_hardware));
1557
1558         DRMLISTFOREACHSAFE(block, tmp, &bufmgr_fake->lru) {
1559                 drm_intel_bo_fake *bo_fake = (drm_intel_bo_fake *) block->bo;
1560                 /* Releases the memory, and memcpys dirty contents out if
1561                  * necessary.
1562                  */
1563                 free_block(bufmgr_fake, block, 0);
1564                 bo_fake->block = NULL;
1565         }
1566
1567         pthread_mutex_unlock(&bufmgr_fake->lock);
1568 }
1569
1570 drm_public void
1571 drm_intel_bufmgr_fake_set_last_dispatch(drm_intel_bufmgr *bufmgr,
1572                                         volatile unsigned int
1573                                         *last_dispatch)
1574 {
1575         drm_intel_bufmgr_fake *bufmgr_fake = (drm_intel_bufmgr_fake *) bufmgr;
1576
1577         bufmgr_fake->last_dispatch = (volatile int *)last_dispatch;
1578 }
1579
1580 drm_public drm_intel_bufmgr *
1581 drm_intel_bufmgr_fake_init(int fd, unsigned long low_offset,
1582                            void *low_virtual, unsigned long size,
1583                            volatile unsigned int *last_dispatch)
1584 {
1585         drm_intel_bufmgr_fake *bufmgr_fake;
1586
1587         bufmgr_fake = calloc(1, sizeof(*bufmgr_fake));
1588
1589         if (pthread_mutex_init(&bufmgr_fake->lock, NULL) != 0) {
1590                 free(bufmgr_fake);
1591                 return NULL;
1592         }
1593
1594         /* Initialize allocator */
1595         DRMINITLISTHEAD(&bufmgr_fake->fenced);
1596         DRMINITLISTHEAD(&bufmgr_fake->on_hardware);
1597         DRMINITLISTHEAD(&bufmgr_fake->lru);
1598
1599         bufmgr_fake->low_offset = low_offset;
1600         bufmgr_fake->virtual = low_virtual;
1601         bufmgr_fake->size = size;
1602         bufmgr_fake->heap = mmInit(low_offset, size);
1603
1604         /* Hook in methods */
1605         bufmgr_fake->bufmgr.bo_alloc = drm_intel_fake_bo_alloc;
1606         bufmgr_fake->bufmgr.bo_alloc_for_render = drm_intel_fake_bo_alloc;
1607         bufmgr_fake->bufmgr.bo_alloc_tiled = drm_intel_fake_bo_alloc_tiled;
1608         bufmgr_fake->bufmgr.bo_reference = drm_intel_fake_bo_reference;
1609         bufmgr_fake->bufmgr.bo_unreference = drm_intel_fake_bo_unreference;
1610         bufmgr_fake->bufmgr.bo_map = drm_intel_fake_bo_map;
1611         bufmgr_fake->bufmgr.bo_unmap = drm_intel_fake_bo_unmap;
1612         bufmgr_fake->bufmgr.bo_subdata = drm_intel_fake_bo_subdata;
1613         bufmgr_fake->bufmgr.bo_wait_rendering =
1614             drm_intel_fake_bo_wait_rendering;
1615         bufmgr_fake->bufmgr.bo_emit_reloc = drm_intel_fake_emit_reloc;
1616         bufmgr_fake->bufmgr.destroy = drm_intel_fake_destroy;
1617         bufmgr_fake->bufmgr.bo_exec = drm_intel_fake_bo_exec;
1618         bufmgr_fake->bufmgr.check_aperture_space =
1619             drm_intel_fake_check_aperture_space;
1620         bufmgr_fake->bufmgr.debug = 0;
1621
1622         bufmgr_fake->fd = fd;
1623         bufmgr_fake->last_dispatch = (volatile int *)last_dispatch;
1624
1625         return &bufmgr_fake->bufmgr;
1626 }