Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2351 Serge 1
/*
2
 * Copyright (c) 2011 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 FROM,
20
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
 * SOFTWARE.
22
 *
23
 * Authors:
24
 *    Chris Wilson 
25
 *
26
 */
27
 
28
 
29
#ifdef HAVE_CONFIG_H
30
#include "config.h"
31
#endif
32
 
33
#include 
34
#include 
35
#include "i915_drm.h"
36
#include "i915_drv.h"
37
#include "intel_drv.h"
38
 
39
#include 
40
#include "../bitmap.h"
41
#include "sna.h"
42
//#include "sna_reg.h"
43
//#include 
44
//#include 
45
 
46
#define NO_CACHE 1
47
 
48
#define list_is_empty list_empty
49
#define list_init     INIT_LIST_HEAD
50
 
51
extern struct drm_device *main_device;
52
 
53
static struct kgem_bo *
54
search_linear_cache(struct kgem *kgem, unsigned int num_pages,
55
                    unsigned flags);
56
 
57
#define INT16_MAX              (32767)
58
 
59
#define PAGE_ALIGN(x) ALIGN(x, PAGE_SIZE)
60
#define NUM_PAGES(x) (((x) + PAGE_SIZE-1) / PAGE_SIZE)
61
 
62
#define MAX_GTT_VMA_CACHE 512
63
#define MAX_CPU_VMA_CACHE INT16_MAX
64
#define MAP_PRESERVE_TIME 10
65
 
66
#define CPU_MAP(ptr) ((void*)((uintptr_t)(ptr) & ~1))
67
#define MAKE_CPU_MAP(ptr) ((void*)((uintptr_t)(ptr) | 1))
68
 
69
struct kgem_partial_bo {
70
	struct kgem_bo base;
71
	void *mem;
72
	uint32_t used;
73
	uint32_t need_io : 1;
74
	uint32_t write : 2;
75
	uint32_t mmapped : 1;
76
};
77
 
78
static struct kgem_bo *__kgem_freed_bo;
79
static struct drm_i915_gem_exec_object2 _kgem_dummy_exec;
80
 
81
static inline int bytes(struct kgem_bo *bo)
82
{
83
	return kgem_bo_size(bo);
84
}
85
 
86
#define bucket(B) (B)->size.pages.bucket
87
#define num_pages(B) (B)->size.pages.count
88
 
89
static void kgem_sna_reset(struct kgem *kgem)
90
{
91
    struct sna *sna = container_of(kgem, struct sna, kgem);
92
 
93
    sna->render.reset(sna);
94
    sna->blt_state.fill_bo = 0;
95
}
96
 
97
static void kgem_sna_flush(struct kgem *kgem)
98
{
99
	struct sna *sna = container_of(kgem, struct sna, kgem);
100
 
101
	sna->render.flush(sna);
102
 
103
	if (sna->render.solid_cache.dirty)
104
		sna_render_flush_solid(sna);
105
}
106
 
107
static int __gem_write(int fd, uint32_t handle,
108
               int offset, int length,
109
               const void *src)
110
{
111
    DBG(("%s(handle=%x, offset=%d, len=%d)\n", __FUNCTION__,
112
         handle, offset, length));
113
 
114
    write_gem_object(handle, offset, length, src);
115
    return 0;
116
}
117
 
118
 
119
static int gem_write(int fd, uint32_t handle,
120
             int offset, int length,
121
             const void *src)
122
{
123
    u32 _offset;
124
    u32 _size;
125
    u8  *data_ptr;
126
 
127
    DBG(("%s(handle=%x, offset=%d, len=%d)\n", __FUNCTION__,
128
         handle, offset, length));
129
 
130
    /* align the transfer to cachelines; fortuitously this is safe! */
131
    if ((offset | length) & 63) {
132
        _offset = offset & ~63;
133
        _size = ALIGN(offset+length, 64) - _offset;
134
        data_ptr = (u8*)src + _offset - offset;
135
    } else {
136
        _offset = offset;
137
        _size = length;
138
        data_ptr = (u8*)src;
139
    }
140
 
141
    write_gem_object(handle, _offset, _size, data_ptr);
142
    return 0;
143
}
144
 
145
static void kgem_bo_retire(struct kgem *kgem, struct kgem_bo *bo)
146
{
147
    DBG(("%s: handle=%x, domain=%d\n",
148
	     __FUNCTION__, bo->handle, bo->domain));
149
	assert(!kgem_busy(kgem, bo->handle));
150
 
151
	if (bo->domain == DOMAIN_GPU)
152
		kgem_retire(kgem);
153
 
154
	if (bo->exec == NULL) {
155
        DBG(("%s: retiring bo handle=%x (needed flush? %d), rq? %d\n",
156
		     __FUNCTION__, bo->handle, bo->needs_flush, bo->rq != NULL));
157
		bo->rq = NULL;
158
		list_del(&bo->request);
159
		bo->needs_flush = bo->flush;
160
	}
161
}
162
 
163
Bool kgem_bo_write(struct kgem *kgem, struct kgem_bo *bo,
164
           const void *data, int length)
165
{
166
    assert(bo->refcnt);
167
    assert(!bo->purged);
168
    assert(!kgem_busy(kgem, bo->handle));
169
 
170
    assert(length <= bytes(bo));
171
    if (gem_write(kgem->fd, bo->handle, 0, length, data))
172
        return FALSE;
173
 
174
    DBG(("%s: flush=%d, domain=%d\n", __FUNCTION__, bo->flush, bo->domain));
175
    kgem_bo_retire(kgem, bo);
176
    bo->domain = DOMAIN_NONE;
177
    return TRUE;
178
}
179
 
180
static uint32_t gem_create(int fd, int num_pages)
181
{
182
    struct drm_i915_gem_object *obj;
183
    int       ret;
184
 
185
    /* Allocate the new object */
186
    obj = i915_gem_alloc_object(main_device,
187
                                PAGE_SIZE * num_pages);
188
    if (obj == NULL)
189
        goto err1;
190
 
191
    ret = i915_gem_object_pin(obj, 4096, true);
192
    if (ret)
193
        goto err2;
194
 
195
    return (uint32_t)obj;
196
 
197
err2:
198
    drm_gem_object_unreference(&obj->base);
199
err1:
200
    return 0;
201
}
202
 
203
static bool
204
kgem_bo_set_purgeable(struct kgem *kgem, struct kgem_bo *bo)
205
{
206
    return true;
207
}
208
 
209
 
210
static bool
211
kgem_bo_clear_purgeable(struct kgem *kgem, struct kgem_bo *bo)
212
{
213
    return true;
214
}
215
 
216
static void gem_close(int fd, uint32_t handle)
217
{
218
    destroy_gem_object(handle);
219
}
220
 
221
 
222
/*
223
constant inline static unsigned long __fls(unsigned long word)
224
{
225
    asm("bsr %1,%0"
226
        : "=r" (word)
227
        : "rm" (word));
228
    return word;
229
}
230
*/
231
 
232
constant inline static int cache_bucket(int num_pages)
233
{
234
    return __fls(num_pages);
235
}
236
 
237
static struct kgem_bo *__kgem_bo_init(struct kgem_bo *bo,
238
                      int handle, int num_pages)
239
{
240
    assert(num_pages);
241
    memset(bo, 0, sizeof(*bo));
242
 
243
    bo->refcnt = 1;
244
    bo->handle = handle;
245
    num_pages(bo) = num_pages;
246
    bucket(bo) = cache_bucket(num_pages);
247
    bo->reusable = true;
248
    bo->domain = DOMAIN_CPU;
249
    list_init(&bo->request);
250
    list_init(&bo->list);
251
    list_init(&bo->vma);
252
 
253
    return bo;
254
}
255
 
256
static struct kgem_bo *__kgem_bo_alloc(int handle, int num_pages)
257
{
258
    struct kgem_bo *bo;
259
 
260
    if (__kgem_freed_bo) {
261
        bo = __kgem_freed_bo;
262
        __kgem_freed_bo = *(struct kgem_bo **)bo;
263
    } else {
264
        bo = malloc(sizeof(*bo));
265
        if (bo == NULL)
266
            return NULL;
267
    }
268
 
269
    return __kgem_bo_init(bo, handle, num_pages);
270
}
271
 
272
static struct kgem_request _kgem_static_request;
273
 
274
static struct kgem_request *__kgem_request_alloc(void)
275
{
276
    struct kgem_request *rq;
277
 
278
    rq = malloc(sizeof(*rq));
279
    if (rq == NULL)
280
        rq = &_kgem_static_request;
281
 
282
    list_init(&rq->buffers);
283
 
284
    return rq;
285
}
286
 
287
static struct list_head *inactive(struct kgem *kgem, int num_pages)
288
{
289
    return &kgem->inactive[cache_bucket(num_pages)];
290
}
291
 
292
static struct list_head *active(struct kgem *kgem, int num_pages, int tiling)
293
{
294
    return &kgem->active[cache_bucket(num_pages)][tiling];
295
}
296
 
297
 
298
 
299
void kgem_init(struct kgem *kgem, int gen)
300
{
301
    struct drm_i915_gem_get_aperture aperture;
302
    struct drm_i915_gem_object     *obj;
303
 
304
    size_t totalram;
305
    unsigned int i, j;
306
    int ret;
307
 
308
    memset(kgem, 0, sizeof(*kgem));
309
 
310
    kgem->gen = gen;
311
    kgem->wedged  = 0;
312
//    kgem->wedged |= DBG_NO_HW;
313
 
314
    obj = i915_gem_alloc_object(main_device, 4096*4);
315
    if (obj == NULL)
316
        goto err2;
317
 
318
    ret = i915_gem_object_pin(obj, 4096, true);
319
    if (ret)
320
        goto err3;
321
 
322
    kgem->batch_ptr = drm_intel_bo_map(obj, true);
323
    kgem->batch = kgem->batch_ptr;
324
    kgem->batch_idx = 0;
325
    kgem->batch_obj = obj;
326
 
327
    kgem->max_batch_size = 1024; //ARRAY_SIZE(kgem->batch);
328
 
329
    kgem->half_cpu_cache_pages = (2048*1024) >> 13;
330
 
331
    list_init(&kgem->partial);
332
    list_init(&kgem->requests);
333
    list_init(&kgem->flushing);
334
    list_init(&kgem->large);
335
    for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++)
336
        list_init(&kgem->inactive[i]);
337
    for (i = 0; i < ARRAY_SIZE(kgem->active); i++) {
338
        for (j = 0; j < ARRAY_SIZE(kgem->active[i]); j++)
339
            list_init(&kgem->active[i][j]);
340
    }
341
    for (i = 0; i < ARRAY_SIZE(kgem->vma); i++) {
342
        for (j = 0; j < ARRAY_SIZE(kgem->vma[i].inactive); j++)
343
            list_init(&kgem->vma[i].inactive[j]);
344
    }
345
    kgem->vma[MAP_GTT].count = -MAX_GTT_VMA_CACHE;
346
    kgem->vma[MAP_CPU].count = -MAX_CPU_VMA_CACHE;
347
 
348
    kgem->next_request = __kgem_request_alloc();
349
 
350
//#if defined(USE_VMAP) && defined(I915_PARAM_HAS_VMAP)
351
//    if (!DBG_NO_VMAP)
352
//        kgem->has_vmap = gem_param(kgem, I915_PARAM_HAS_VMAP) > 0;
353
//#endif
354
//    DBG(("%s: using vmap=%d\n", __FUNCTION__, kgem->has_vmap));
355
 
356
    if (gen < 40) {
357
//        if (!DBG_NO_RELAXED_FENCING) {
358
//            kgem->has_relaxed_fencing =
359
//                gem_param(kgem, I915_PARAM_HAS_RELAXED_FENCING) > 0;
360
//        }
361
    } else
362
        kgem->has_relaxed_fencing = 1;
363
    DBG(("%s: has relaxed fencing? %d\n", __FUNCTION__,
364
         kgem->has_relaxed_fencing));
365
 
366
    kgem->has_llc = (gen >= 60)?true:false;
367
    kgem->has_cpu_bo = kgem->has_llc;
368
    DBG(("%s: cpu bo enabled %d: llc? %d\n", __FUNCTION__,
369
         kgem->has_cpu_bo, kgem->has_llc));
370
 
371
    kgem->has_semaphores = false;
372
//    if (gen >= 60 && semaphores_enabled())
373
//        kgem->has_semaphores = true;
374
//    DBG(("%s: semaphores enabled? %d\n", __FUNCTION__,
375
//         kgem->has_semaphores));
376
 
377
    VG_CLEAR(aperture);
378
    aperture.aper_size = 64*1024*1024;
379
    i915_gem_get_aperture_ioctl(main_device, &aperture, NULL);
380
    kgem->aperture_total = aperture.aper_size;
381
    kgem->aperture_high = aperture.aper_size * 3/4;
382
    kgem->aperture_low = aperture.aper_size * 1/3;
383
    DBG(("%s: aperture low=%d [%d], high=%d [%d]\n", __FUNCTION__,
384
         kgem->aperture_low, kgem->aperture_low / (1024*1024),
385
         kgem->aperture_high, kgem->aperture_high / (1024*1024)));
386
 
387
    kgem->aperture_mappable = aperture.aper_size;
388
    DBG(("%s: aperture mappable=%d [%d MiB]\n", __FUNCTION__,
389
         kgem->aperture_mappable, kgem->aperture_mappable / (1024*1024)));
390
 
391
    kgem->partial_buffer_size = 64 * 1024;
392
    while (kgem->partial_buffer_size < kgem->aperture_mappable >> 10)
393
        kgem->partial_buffer_size *= 2;
394
    DBG(("%s: partial buffer size=%d [%d KiB]\n", __FUNCTION__,
395
         kgem->partial_buffer_size, kgem->partial_buffer_size / 1024));
396
 
397
    kgem->min_alignment = 4;
398
    if (gen < 60)
399
        /* XXX workaround an issue where we appear to fail to
400
         * disable dual-stream mode */
401
        kgem->min_alignment = 64;
402
 
403
    kgem->max_object_size = 2 * kgem->aperture_total / 3;
404
    kgem->max_cpu_size = kgem->max_object_size;
405
    kgem->max_gpu_size = kgem->max_object_size;
406
    if (!kgem->has_llc)
407
        kgem->max_gpu_size = MAX_CACHE_SIZE;
408
    if (gen < 40) {
409
        /* If we have to use fences for blitting, we have to make
410
         * sure we can fit them into the aperture.
411
         */
412
        kgem->max_gpu_size = kgem->aperture_mappable / 2;
413
        if (kgem->max_gpu_size > kgem->aperture_low)
414
            kgem->max_gpu_size = kgem->aperture_low;
415
    }
416
    if (kgem->max_gpu_size > kgem->max_cpu_size)
417
        kgem->max_gpu_size = kgem->max_cpu_size;
418
 
419
    kgem->max_upload_tile_size = kgem->aperture_mappable / 2;
420
    if (kgem->max_upload_tile_size > kgem->max_gpu_size / 2)
421
        kgem->max_upload_tile_size = kgem->max_gpu_size / 2;
422
 
423
    kgem->max_copy_tile_size = (MAX_CACHE_SIZE + 1)/2;
424
    if (kgem->max_copy_tile_size > kgem->max_gpu_size / 2)
425
        kgem->max_copy_tile_size = kgem->max_gpu_size / 2;
426
 
427
    totalram = 1024*1024; //total_ram_size();
428
    if (totalram == 0) {
429
        DBG(("%s: total ram size unknown, assuming maximum of total aperture\n",
430
             __FUNCTION__));
431
        totalram = kgem->aperture_total;
432
    }
433
    if (kgem->max_object_size > totalram / 2)
434
        kgem->max_object_size = totalram / 2;
435
    if (kgem->max_cpu_size > totalram / 2)
436
        kgem->max_cpu_size = totalram / 2;
437
    if (kgem->max_gpu_size > totalram / 4)
438
        kgem->max_gpu_size = totalram / 4;
439
 
440
    kgem->large_object_size = MAX_CACHE_SIZE;
441
    if (kgem->large_object_size > kgem->max_gpu_size)
442
        kgem->large_object_size = kgem->max_gpu_size;
443
 
444
    DBG(("%s: large object thresold=%d\n",
445
         __FUNCTION__, kgem->large_object_size));
446
    DBG(("%s: max object size (gpu=%d, cpu=%d, tile upload=%d, copy=%d)\n",
447
         __FUNCTION__,
448
         kgem->max_gpu_size, kgem->max_cpu_size,
449
         kgem->max_upload_tile_size, kgem->max_copy_tile_size));
450
 
451
    /* Convert the aperture thresholds to pages */
452
    kgem->aperture_low /= PAGE_SIZE;
453
    kgem->aperture_high /= PAGE_SIZE;
454
 
455
//    kgem->fence_max = gem_param(kgem, I915_PARAM_NUM_FENCES_AVAIL) - 2;
456
//    if ((int)kgem->fence_max < 0)
457
        kgem->fence_max = 5; /* minimum safe value for all hw */
458
    DBG(("%s: max fences=%d\n", __FUNCTION__, kgem->fence_max));
459
err3:
460
err2:
461
    return;
462
}
463
 
464
static struct drm_i915_gem_exec_object2 *
465
kgem_add_handle(struct kgem *kgem, struct kgem_bo *bo)
466
{
467
	struct drm_i915_gem_exec_object2 *exec;
468
 
469
	DBG(("%s: handle=%d, index=%d\n",
470
	     __FUNCTION__, bo->handle, kgem->nexec));
471
 
472
	assert(kgem->nexec < ARRAY_SIZE(kgem->exec));
473
	exec = memset(&kgem->exec[kgem->nexec++], 0, sizeof(*exec));
474
	exec->handle = bo->handle;
475
	exec->offset = bo->presumed_offset;
476
 
477
	kgem->aperture += num_pages(bo);
478
 
479
	return exec;
480
}
481
 
482
void _kgem_add_bo(struct kgem *kgem, struct kgem_bo *bo)
483
{
484
	bo->exec = kgem_add_handle(kgem, bo);
485
	bo->rq = kgem->next_request;
486
 
487
	list_move(&bo->request, &kgem->next_request->buffers);
488
 
489
	/* XXX is it worth working around gcc here? */
490
	kgem->flush |= bo->flush;
491
	kgem->sync |= bo->sync;
492
	kgem->scanout |= bo->scanout;
493
}
494
 
495
static uint32_t kgem_end_batch(struct kgem *kgem)
496
{
497
//	kgem->context_switch(kgem, KGEM_NONE);
498
 
499
	kgem->batch[kgem->nbatch++] = MI_BATCH_BUFFER_END;
500
	if (kgem->nbatch & 1)
501
		kgem->batch[kgem->nbatch++] = MI_NOOP;
502
 
503
	return kgem->nbatch;
504
}
505
 
506
static void kgem_fixup_self_relocs(struct kgem *kgem, struct kgem_bo *bo)
507
{
508
	int n;
509
 
510
    for (n = 0; n < kgem->nreloc; n++)
511
    {
512
        if (kgem->reloc[n].target_handle == 0)
513
        {
514
			kgem->reloc[n].target_handle = bo->handle;
515
			kgem->reloc[n].presumed_offset = bo->presumed_offset;
516
			kgem->batch[kgem->reloc[n].offset/sizeof(kgem->batch[0])] =
517
				kgem->reloc[n].delta + bo->presumed_offset;
518
 
519
            dbgprintf("fixup reloc %d pos %d handle %d delta %x \n",
520
                       n, kgem->reloc[n].offset/sizeof(kgem->batch[0]),
521
                       bo->handle, kgem->reloc[n].delta);
522
		}
523
	}
524
}
525
 
526
static void kgem_bo_binding_free(struct kgem *kgem, struct kgem_bo *bo)
527
{
528
	struct kgem_bo_binding *b;
529
 
530
	b = bo->binding.next;
531
	while (b) {
532
		struct kgem_bo_binding *next = b->next;
533
		free (b);
534
		b = next;
535
	}
536
}
537
 
538
static void kgem_bo_release_map(struct kgem *kgem, struct kgem_bo *bo)
539
{
540
	int type = IS_CPU_MAP(bo->map);
541
 
542
	DBG(("%s: releasing %s vma for handle=%d, count=%d\n",
543
	     __FUNCTION__, type ? "CPU" : "GTT",
544
	     bo->handle, kgem->vma[type].count));
545
 
546
	VG(if (type) VALGRIND_FREELIKE_BLOCK(CPU_MAP(bo->map), 0));
547
//	munmap(CPU_MAP(bo->map), bytes(bo));
548
	bo->map = NULL;
549
 
550
	if (!list_is_empty(&bo->vma)) {
551
		list_del(&bo->vma);
552
		kgem->vma[type].count--;
553
	}
554
}
555
 
556
static void kgem_bo_free(struct kgem *kgem, struct kgem_bo *bo)
557
{
558
    DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
559
    assert(bo->refcnt == 0);
560
    assert(bo->exec == NULL);
561
 
562
    kgem_bo_binding_free(kgem, bo);
563
 
564
    if (bo->map)
565
        kgem_bo_release_map(kgem, bo);
566
    assert(list_is_empty(&bo->vma));
567
 
568
    list_del(&bo->list);
569
    list_del(&bo->request);
570
    gem_close(kgem->fd, bo->handle);
571
 
572
    if (!bo->io) {
573
        *(struct kgem_bo **)bo = __kgem_freed_bo;
574
        __kgem_freed_bo = bo;
575
    } else
576
        free(bo);
577
}
578
 
579
inline static void kgem_bo_move_to_inactive(struct kgem *kgem,
580
                        struct kgem_bo *bo)
581
{
582
    assert(!kgem_busy(kgem, bo->handle));
583
    assert(!bo->proxy);
584
    assert(!bo->io);
585
    assert(!bo->needs_flush);
586
    assert(bo->rq == NULL);
587
    assert(bo->domain != DOMAIN_GPU);
588
 
589
    if (bucket(bo) >= NUM_CACHE_BUCKETS) {
590
        kgem_bo_free(kgem, bo);
591
        return;
592
    }
593
 
594
    list_move(&bo->list, &kgem->inactive[bucket(bo)]);
595
    if (bo->map) {
596
        int type = IS_CPU_MAP(bo->map);
597
        if (bucket(bo) >= NUM_CACHE_BUCKETS ||
598
            (!type && !kgem_bo_is_mappable(kgem, bo))) {
599
            list_del(&bo->vma);
600
//            munmap(CPU_MAP(bo->map), bytes(bo));
601
            bo->map = NULL;
602
        }
603
        if (bo->map) {
604
            list_move(&bo->vma, &kgem->vma[type].inactive[bucket(bo)]);
605
            kgem->vma[type].count++;
606
        }
607
    }
608
 
609
    kgem->need_expire = true;
610
}
611
 
612
inline static void kgem_bo_remove_from_inactive(struct kgem *kgem,
613
                        struct kgem_bo *bo)
614
{
615
    list_del(&bo->list);
616
    assert(bo->rq == NULL);
617
    if (bo->map) {
618
        assert(!list_is_empty(&bo->vma));
619
        list_del(&bo->vma);
620
        kgem->vma[IS_CPU_MAP(bo->map)].count--;
621
    }
622
}
623
 
624
inline static void kgem_bo_remove_from_active(struct kgem *kgem,
625
                          struct kgem_bo *bo)
626
{
627
    list_del(&bo->list);
628
    if (bo->rq == &_kgem_static_request)
629
        list_del(&bo->request);
630
    assert(list_is_empty(&bo->vma));
631
}
632
 
633
static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
634
{
635
    DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
636
 
637
    assert(list_is_empty(&bo->list));
638
    assert(bo->refcnt == 0);
639
 
640
    bo->binding.offset = 0;
641
 
642
    if (NO_CACHE)
643
        goto destroy;
644
 
645
    if (bo->io) {
646
        struct kgem_bo *base;
647
 
648
        base = malloc(sizeof(*base));
649
        if (base) {
650
            DBG(("%s: transferring io handle=%d to bo\n",
651
                 __FUNCTION__, bo->handle));
652
            /* transfer the handle to a minimum bo */
653
            memcpy(base, bo, sizeof (*base));
654
            base->reusable = true;
655
            base->io = false;
656
            list_init(&base->list);
657
            list_replace(&bo->request, &base->request);
658
            list_replace(&bo->vma, &base->vma);
659
            free(bo);
660
            bo = base;
661
        }
662
    }
663
 
664
    if (!bo->reusable) {
665
        DBG(("%s: handle=%d, not reusable\n",
666
             __FUNCTION__, bo->handle));
667
        goto destroy;
668
    }
669
 
670
    if (!kgem->has_llc && IS_CPU_MAP(bo->map) && bo->domain != DOMAIN_CPU)
671
        kgem_bo_release_map(kgem, bo);
672
 
673
    assert(list_is_empty(&bo->vma));
674
    assert(list_is_empty(&bo->list));
675
    assert(bo->vmap == false && bo->sync == false);
676
    assert(bo->io == false);
677
 
678
    bo->scanout = bo->flush = false;
679
    if (bo->rq) {
680
        struct list *cache;
681
 
682
        DBG(("%s: handle=%d -> active\n", __FUNCTION__, bo->handle));
683
        if (bucket(bo) < NUM_CACHE_BUCKETS)
684
            cache = &kgem->active[bucket(bo)][bo->tiling];
685
        else
686
            cache = &kgem->large;
687
        list_add(&bo->list, cache);
688
        return;
689
    }
690
 
691
    assert(bo->exec == NULL);
692
    assert(list_is_empty(&bo->request));
693
/*
694
    if (bo->needs_flush) {
695
        if ((bo->needs_flush = kgem_busy(kgem, bo->handle))) {
696
            struct list *cache;
697
 
698
            DBG(("%s: handle=%d -> flushing\n",
699
                 __FUNCTION__, bo->handle));
700
 
701
            list_add(&bo->request, &kgem->flushing);
702
            if (bucket(bo) < NUM_CACHE_BUCKETS)
703
                cache = &kgem->active[bucket(bo)][bo->tiling];
704
            else
705
                cache = &kgem->large;
706
            list_add(&bo->list, cache);
707
            bo->rq = &_kgem_static_request;
708
            return;
709
        }
710
 
711
        bo->domain = DOMAIN_NONE;
712
    }
713
*/
714
    if (!IS_CPU_MAP(bo->map)) {
715
        if (!kgem_bo_set_purgeable(kgem, bo))
716
            goto destroy;
717
 
718
        if (!kgem->has_llc && bo->domain == DOMAIN_CPU)
719
            goto destroy;
720
 
721
        DBG(("%s: handle=%d, purged\n",
722
             __FUNCTION__, bo->handle));
723
    }
724
 
725
    DBG(("%s: handle=%d -> inactive\n", __FUNCTION__, bo->handle));
726
    kgem_bo_move_to_inactive(kgem, bo);
727
    return;
728
 
729
destroy:
730
    if (!bo->exec)
731
        kgem_bo_free(kgem, bo);
732
}
733
 
734
 
735
 
736
 
737
 
738
bool kgem_retire(struct kgem *kgem)
739
{
740
    struct kgem_bo *bo, *next;
741
    bool retired = false;
742
 
743
    DBG(("%s\n", __FUNCTION__));
744
 
745
    list_for_each_entry_safe(bo, next, &kgem->flushing, request) {
746
        assert(bo->refcnt == 0);
747
        assert(bo->rq == &_kgem_static_request);
748
        assert(bo->exec == NULL);
749
 
750
//        if (kgem_busy(kgem, bo->handle))
751
//            break;
752
 
753
        DBG(("%s: moving %d from flush to inactive\n",
754
             __FUNCTION__, bo->handle));
755
        if (kgem_bo_set_purgeable(kgem, bo)) {
756
            bo->needs_flush = false;
757
            bo->domain = DOMAIN_NONE;
758
            bo->rq = NULL;
759
            list_del(&bo->request);
760
            kgem_bo_move_to_inactive(kgem, bo);
761
        } else
762
            kgem_bo_free(kgem, bo);
763
 
764
        retired = true;
765
    }
766
 
767
    while (!list_is_empty(&kgem->requests)) {
768
        struct kgem_request *rq;
769
 
770
        rq = list_first_entry(&kgem->requests,
771
                      struct kgem_request,
772
                      list);
773
//        if (kgem_busy(kgem, rq->bo->handle))
774
//            break;
775
 
776
        DBG(("%s: request %d complete\n",
777
             __FUNCTION__, rq->bo->handle));
778
 
779
        while (!list_is_empty(&rq->buffers)) {
780
            bo = list_first_entry(&rq->buffers,
781
                          struct kgem_bo,
782
                          request);
783
 
784
            assert(bo->rq == rq);
785
            assert(bo->exec == NULL);
786
            assert(bo->domain == DOMAIN_GPU);
787
 
788
            list_del(&bo->request);
789
            bo->rq = NULL;
790
 
791
//            if (bo->needs_flush)
792
//                bo->needs_flush = kgem_busy(kgem, bo->handle);
793
            if (!bo->needs_flush)
794
                bo->domain = DOMAIN_NONE;
795
 
796
            if (bo->refcnt)
797
                continue;
798
 
799
            if (!bo->reusable) {
800
                DBG(("%s: closing %d\n",
801
                     __FUNCTION__, bo->handle));
802
                kgem_bo_free(kgem, bo);
803
                continue;
804
            }
805
 
806
            if (bo->needs_flush) {
807
                DBG(("%s: moving %d to flushing\n",
808
                     __FUNCTION__, bo->handle));
809
                list_add(&bo->request, &kgem->flushing);
810
                bo->rq = &_kgem_static_request;
811
            } else if (kgem_bo_set_purgeable(kgem, bo)) {
812
                DBG(("%s: moving %d to inactive\n",
813
                     __FUNCTION__, bo->handle));
814
                kgem_bo_move_to_inactive(kgem, bo);
815
                retired = true;
816
            } else {
817
                DBG(("%s: closing %d\n",
818
                     __FUNCTION__, bo->handle));
819
                kgem_bo_free(kgem, bo);
820
            }
821
        }
822
 
823
        rq->bo->refcnt--;
824
        assert(rq->bo->refcnt == 0);
825
        assert(rq->bo->rq == NULL);
826
        assert(list_is_empty(&rq->bo->request));
827
        if (kgem_bo_set_purgeable(kgem, rq->bo)) {
828
            kgem_bo_move_to_inactive(kgem, rq->bo);
829
            retired = true;
830
        } else {
831
            DBG(("%s: closing %d\n",
832
                 __FUNCTION__, rq->bo->handle));
833
            kgem_bo_free(kgem, rq->bo);
834
        }
835
 
836
        list_del(&rq->list);
837
        free(rq);
838
    }
839
 
840
    kgem->need_retire = !list_is_empty(&kgem->requests);
841
    DBG(("%s -- need_retire=%d\n", __FUNCTION__, kgem->need_retire));
842
 
843
    kgem->retire(kgem);
844
 
845
    return retired;
846
}
847
 
848
 
849
 
850
 
851
 
852
 
853
 
854
 
855
 
856
 
857
 
858
 
859
 
860
 
861
 
862
 
863
 
864
 
865
 
866
 
867
 
868
 
869
 
870
 
871
 
872
 
873
 
874
 
875
 
876
 
877
 
878
 
879
 
880
 
881
 
882
 
883
 
884
 
885
 
886
 
887
 
888
static int kgem_batch_write(struct kgem *kgem, uint32_t handle, uint32_t size)
889
{
890
	int ret;
891
 
892
	assert(!kgem_busy(kgem, handle));
893
 
894
	/* If there is no surface data, just upload the batch */
895
	if (kgem->surface == kgem->max_batch_size)
896
		return gem_write(kgem->fd, handle,
897
				 0, sizeof(uint32_t)*kgem->nbatch,
898
				 kgem->batch);
899
 
900
	/* Are the batch pages conjoint with the surface pages? */
901
	if (kgem->surface < kgem->nbatch + PAGE_SIZE/4) {
902
		assert(size == sizeof(kgem->batch));
903
		return gem_write(kgem->fd, handle,
904
				 0, sizeof(kgem->batch),
905
				 kgem->batch);
906
	}
907
 
908
	/* Disjoint surface/batch, upload separately */
909
	ret = gem_write(kgem->fd, handle,
910
			0, sizeof(uint32_t)*kgem->nbatch,
911
			kgem->batch);
912
	if (ret)
913
		return ret;
914
 
915
   assert(kgem->nbatch*sizeof(uint32_t) <=
916
	       sizeof(uint32_t)*kgem->surface - (sizeof(kgem->batch)-size));
917
   return __gem_write(kgem->fd, handle,
918
			sizeof(uint32_t)*kgem->surface - (sizeof(kgem->batch)-size),
919
			sizeof(kgem->batch) - sizeof(uint32_t)*kgem->surface,
920
           kgem->batch + kgem->surface);
921
}
922
 
923
void kgem_reset(struct kgem *kgem)
924
{
925
//    ENTER();
926
 
927
    kgem->nfence = 0;
928
    kgem->nexec = 0;
929
    kgem->nreloc = 0;
930
    kgem->aperture = 0;
931
    kgem->aperture_fenced = 0;
932
    kgem->nbatch = 0;
933
    kgem->surface = kgem->max_batch_size;
934
    kgem->mode = KGEM_NONE;
935
    kgem->flush = 0;
936
    kgem->scanout = 0;
937
 
938
    kgem->batch = kgem->batch_ptr+1024*kgem->batch_idx;
939
 
940
    kgem->next_request = __kgem_request_alloc();
941
 
942
    kgem_sna_reset(kgem);
943
//    dbgprintf("surface %x\n", kgem->surface);
944
//    LEAVE();
945
}
946
 
947
static int compact_batch_surface(struct kgem *kgem)
948
{
949
	int size, shrink, n;
950
 
951
	/* See if we can pack the contents into one or two pages */
952
	size = kgem->max_batch_size - kgem->surface + kgem->nbatch;
953
	if (size > 2048)
954
		return sizeof(kgem->batch);
955
	else if (size > 1024)
956
		size = 8192, shrink = 2*4096;
957
	else
958
		size = 4096, shrink = 3*4096;
959
 
960
 
961
	for (n = 0; n < kgem->nreloc; n++) {
962
		if (kgem->reloc[n].read_domains == I915_GEM_DOMAIN_INSTRUCTION &&
963
		    kgem->reloc[n].target_handle == 0)
964
			kgem->reloc[n].delta -= shrink;
965
 
966
		if (kgem->reloc[n].offset >= size)
967
			kgem->reloc[n].offset -= shrink;
968
	}
969
 
970
	return size;
971
}
972
 
973
void execute_buffer (struct drm_i915_gem_object *buffer, uint32_t offset,
974
                     int size);
975
 
976
void _kgem_submit(struct kgem *kgem)
977
{
978
	struct kgem_request *rq;
979
	uint32_t batch_end;
980
	int size;
981
 
982
	assert(!DBG_NO_HW);
983
 
984
	assert(kgem->nbatch);
985
	assert(kgem->nbatch <= KGEM_BATCH_SIZE(kgem));
986
	assert(kgem->nbatch <= kgem->surface);
987
 
988
	batch_end = kgem_end_batch(kgem);
989
	kgem_sna_flush(kgem);
990
 
991
	DBG(("batch[%d/%d]: %d %d %d, nreloc=%d, nexec=%d, nfence=%d, aperture=%d\n",
992
	     kgem->mode, kgem->ring, batch_end, kgem->nbatch, kgem->surface,
993
	     kgem->nreloc, kgem->nexec, kgem->nfence, kgem->aperture));
994
 
995
	assert(kgem->nbatch <= kgem->max_batch_size);
996
	assert(kgem->nbatch <= kgem->surface);
997
	assert(kgem->nreloc <= ARRAY_SIZE(kgem->reloc));
998
	assert(kgem->nexec < ARRAY_SIZE(kgem->exec));
999
	assert(kgem->nfence <= kgem->fence_max);
1000
 
1001
//   kgem_finish_partials(kgem);
1002
 
1003
	rq = kgem->next_request;
1004
//   if (kgem->surface != kgem->max_batch_size)
1005
//       size = compact_batch_surface(kgem);
1006
//   else
1007
		size = kgem->nbatch * sizeof(kgem->batch[0]);
1008
#if 0
1009
    {
1010
        int i;
1011
 
1012
        dbgprintf("\nDump batch\n\n");
1013
 
1014
        for(i=0; i < kgem->nbatch; i++)
1015
        {
1016
            dbgprintf("\t0x%08x,\t/* %d */\n",
1017
                      kgem->batch[i], i);
1018
        }
1019
        dbgprintf("\ndone\n");
1020
    };
1021
#endif
1022
 
1023
    execute_buffer(kgem->batch_obj, kgem->batch_idx*4096, sizeof(uint32_t)*kgem->nbatch);
1024
 
1025
//   if (kgem->wedged)
1026
//       kgem_cleanup(kgem);
1027
 
1028
    kgem->batch_idx++;
1029
    kgem->batch_idx&= 3;
1030
 
1031
	kgem->flush_now = kgem->scanout;
1032
	kgem_reset(kgem);
1033
 
1034
	assert(kgem->next_request != NULL);
1035
}
1036
 
1037
static struct kgem_bo *
1038
search_linear_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags)
1039
{
1040
    struct kgem_bo *bo, *first = NULL;
1041
    bool use_active = (flags & CREATE_INACTIVE) == 0;
1042
    struct list_head *cache;
1043
 
1044
    if (num_pages >= MAX_CACHE_SIZE / PAGE_SIZE)
1045
        return NULL;
1046
 
1047
    if (!use_active &&
1048
        list_is_empty(inactive(kgem, num_pages)) &&
1049
        !list_is_empty(active(kgem, num_pages, I915_TILING_NONE)) &&
1050
        !kgem_retire(kgem))
1051
        return NULL;
1052
 
1053
    if (!use_active && flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
1054
        int for_cpu = !!(flags & CREATE_CPU_MAP);
1055
        cache = &kgem->vma[for_cpu].inactive[cache_bucket(num_pages)];
1056
        list_for_each_entry(bo, cache, vma) {
1057
            assert(IS_CPU_MAP(bo->map) == for_cpu);
1058
            assert(bucket(bo) == cache_bucket(num_pages));
1059
 
1060
            if (num_pages > num_pages(bo)) {
1061
                DBG(("inactive too small: %d < %d\n",
1062
                     num_pages(bo), num_pages));
1063
                continue;
1064
            }
1065
 
1066
            if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
1067
                kgem_bo_free(kgem, bo);
1068
                break;
1069
            }
1070
 
1071
//            if (I915_TILING_NONE != bo->tiling &&
1072
//                gem_set_tiling(kgem->fd, bo->handle,
1073
//                       I915_TILING_NONE, 0) != I915_TILING_NONE)
1074
//                continue;
1075
 
1076
            kgem_bo_remove_from_inactive(kgem, bo);
1077
 
1078
            bo->tiling = I915_TILING_NONE;
1079
            bo->pitch = 0;
1080
            bo->delta = 0;
1081
            DBG(("  %s: found handle=%d (num_pages=%d) in linear vma cache\n",
1082
                 __FUNCTION__, bo->handle, num_pages(bo)));
1083
            assert(use_active || bo->domain != DOMAIN_GPU);
1084
            assert(!bo->needs_flush);
1085
            //assert(!kgem_busy(kgem, bo->handle));
1086
            return bo;
1087
        }
1088
    }
1089
 
1090
    cache = use_active ? active(kgem, num_pages, I915_TILING_NONE) : inactive(kgem, num_pages);
1091
    list_for_each_entry(bo, cache, list) {
1092
        assert(bo->refcnt == 0);
1093
        assert(bo->reusable);
1094
        assert(!!bo->rq == !!use_active);
1095
 
1096
        if (num_pages > num_pages(bo))
1097
            continue;
1098
 
1099
        if (use_active && bo->tiling != I915_TILING_NONE)
1100
            continue;
1101
 
1102
        if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
1103
            kgem_bo_free(kgem, bo);
1104
            break;
1105
        }
1106
/*
1107
        if (I915_TILING_NONE != bo->tiling) {
1108
            if (use_active)
1109
                continue;
1110
 
1111
            if (gem_set_tiling(kgem->fd, bo->handle,
1112
                       I915_TILING_NONE, 0) != I915_TILING_NONE)
1113
                continue;
1114
 
1115
            bo->tiling = I915_TILING_NONE;
1116
        }
1117
*/
1118
        if (bo->map) {
1119
            if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
1120
                int for_cpu = !!(flags & CREATE_CPU_MAP);
1121
                if (IS_CPU_MAP(bo->map) != for_cpu) {
1122
                    if (first != NULL)
1123
                        break;
1124
 
1125
                    first = bo;
1126
                    continue;
1127
                }
1128
            } else {
1129
                if (first != NULL)
1130
                    break;
1131
 
1132
                first = bo;
1133
                continue;
1134
            }
1135
        } else {
1136
            if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
1137
                if (first != NULL)
1138
                    break;
1139
 
1140
                first = bo;
1141
                continue;
1142
            }
1143
        }
1144
 
1145
        if (use_active)
1146
            kgem_bo_remove_from_active(kgem, bo);
1147
        else
1148
            kgem_bo_remove_from_inactive(kgem, bo);
1149
 
1150
        assert(bo->tiling == I915_TILING_NONE);
1151
        bo->pitch = 0;
1152
        bo->delta = 0;
1153
        DBG(("  %s: found handle=%d (num_pages=%d) in linear %s cache\n",
1154
             __FUNCTION__, bo->handle, num_pages(bo),
1155
             use_active ? "active" : "inactive"));
1156
        assert(use_active || bo->domain != DOMAIN_GPU);
1157
        assert(!bo->needs_flush || use_active);
1158
        //assert(use_active || !kgem_busy(kgem, bo->handle));
1159
        return bo;
1160
    }
1161
 
1162
    if (first) {
1163
        assert(first->tiling == I915_TILING_NONE);
1164
 
1165
        if (use_active)
1166
            kgem_bo_remove_from_active(kgem, first);
1167
        else
1168
            kgem_bo_remove_from_inactive(kgem, first);
1169
 
1170
        first->pitch = 0;
1171
        first->delta = 0;
1172
        DBG(("  %s: found handle=%d (num_pages=%d) in linear %s cache\n",
1173
             __FUNCTION__, first->handle, num_pages(first),
1174
             use_active ? "active" : "inactive"));
1175
        assert(use_active || first->domain != DOMAIN_GPU);
1176
        assert(!first->needs_flush || use_active);
1177
        //assert(use_active || !kgem_busy(kgem, first->handle));
1178
        return first;
1179
    }
1180
 
1181
    return NULL;
1182
}
1183
 
1184
 
1185
 
1186
 
1187
 
1188
 
1189
struct kgem_bo *kgem_create_linear(struct kgem *kgem, int size)
1190
{
1191
    struct kgem_bo *bo;
1192
    uint32_t handle;
1193
 
1194
    DBG(("%s(%d)\n", __FUNCTION__, size));
1195
 
1196
    size = (size + PAGE_SIZE - 1) / PAGE_SIZE;
1197
    bo = search_linear_cache(kgem, size, CREATE_INACTIVE);
1198
    if (bo)
1199
        return kgem_bo_reference(bo);
1200
 
1201
    handle = gem_create(kgem->fd, size);
1202
    if (handle == 0)
1203
        return NULL;
1204
 
1205
    DBG(("%s: new handle=%x\n", __FUNCTION__, handle));
1206
    bo = __kgem_bo_alloc(handle, size);
1207
    if (bo == NULL) {
1208
        gem_close(kgem->fd, handle);
1209
        return NULL;
1210
    }
1211
    struct drm_i915_gem_object *obj;
1212
    obj = (void*)handle;
1213
 
1214
    bo->gaddr = obj->gtt_offset;
1215
    return bo;
1216
}
1217
 
1218
 
1219
 
1220
 
1221
 
1222
 
1223
inline int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo)
1224
{
1225
	unsigned int size;
1226
 
1227
	assert(bo->tiling);
1228
	assert(kgem->gen < 40);
1229
 
1230
	if (kgem->gen < 30)
1231
		size = 512 * 1024;
1232
	else
1233
		size = 1024 * 1024;
1234
	while (size < bytes(bo))
1235
		size *= 2;
1236
 
1237
	return size;
1238
}
1239
 
1240
 
1241
 
1242
 
1243
 
1244
 
1245
 
1246
 
1247
 
1248
 
1249
 
1250
 
1251
 
1252
 
1253
 
1254
 
1255
 
1256
 
1257
 
1258
 
1259
 
1260
 
1261
 
1262
 
1263
 
1264
 
1265
 
1266
 
1267
 
1268
 
1269
 
1270
 
1271
 
1272
 
1273
 
1274
 
1275
 
1276
 
1277
 
1278
 
1279
 
1280
 
1281
 
1282
 
1283
 
1284
 
1285
 
1286
 
1287
void _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
1288
{
1289
//    if (bo->proxy) {
1290
//        assert(bo->map == NULL);
1291
//        if (bo->io && bo->exec == NULL)
1292
//            _kgem_bo_delete_partial(kgem, bo);
1293
//        kgem_bo_unref(kgem, bo->proxy);
1294
//        kgem_bo_binding_free(kgem, bo);
1295
//        _list_del(&bo->request);
1296
//        free(bo);
1297
//        return;
1298
//    }
1299
 
1300
//    if (bo->vmap)
1301
//        kgem_bo_sync__cpu(kgem, bo);
1302
 
1303
    __kgem_bo_destroy(kgem, bo);
1304
}
1305
 
1306
void __kgem_flush(struct kgem *kgem, struct kgem_bo *bo)
1307
{
1308
	/* The kernel will emit a flush *and* update its own flushing lists. */
1309
//	kgem_busy(kgem, bo->handle);
1310
}
1311
 
1312
bool kgem_check_bo(struct kgem *kgem, ...)
1313
{
1314
    va_list ap;
1315
    struct kgem_bo *bo;
1316
    int num_exec = 0;
1317
    int num_pages = 0;
1318
 
1319
    va_start(ap, kgem);
1320
    while ((bo = va_arg(ap, struct kgem_bo *))) {
1321
        if (bo->exec)
1322
            continue;
1323
 
1324
        if (bo->proxy) {
1325
            bo = bo->proxy;
1326
            if (bo->exec)
1327
                continue;
1328
        }
1329
        num_pages += num_pages(bo);
1330
        num_exec++;
1331
    }
1332
    va_end(ap);
1333
 
1334
    if (!num_pages)
1335
        return true;
1336
 
1337
    if (kgem->aperture > kgem->aperture_low)
1338
        return false;
1339
 
1340
    if (num_pages + kgem->aperture > kgem->aperture_high)
1341
        return false;
1342
 
1343
    if (kgem->nexec + num_exec >= KGEM_EXEC_SIZE(kgem))
1344
        return false;
1345
 
1346
    return true;
1347
}
1348
 
1349
/*
1350
bool kgem_check_bo_fenced(struct kgem *kgem, ...)
1351
{
1352
	va_list ap;
1353
	struct kgem_bo *bo;
1354
	int num_fence = 0;
1355
	int num_exec = 0;
1356
	int num_pages = 0;
1357
	int fenced_size = 0;
1358
 
1359
	va_start(ap, kgem);
1360
	while ((bo = va_arg(ap, struct kgem_bo *))) {
1361
		if (bo->proxy)
1362
			bo = bo->proxy;
1363
		if (bo->exec) {
1364
			if (kgem->gen >= 40 || bo->tiling == I915_TILING_NONE)
1365
				continue;
1366
 
1367
			if ((bo->exec->flags & EXEC_OBJECT_NEEDS_FENCE) == 0) {
1368
				fenced_size += kgem_bo_fenced_size(kgem, bo);
1369
				num_fence++;
1370
			}
1371
 
1372
			continue;
1373
		}
1374
 
1375
		num_pages += num_pages(bo);
1376
		num_exec++;
1377
		if (kgem->gen < 40 && bo->tiling) {
1378
			fenced_size += kgem_bo_fenced_size(kgem, bo);
1379
			num_fence++;
1380
		}
1381
	}
1382
	va_end(ap);
1383
 
1384
	if (fenced_size + kgem->aperture_fenced > kgem->aperture_mappable)
1385
		return false;
1386
 
1387
	if (kgem->nfence + num_fence > kgem->fence_max)
1388
		return false;
1389
 
1390
	if (!num_pages)
1391
		return true;
1392
 
1393
	if (kgem->aperture > kgem->aperture_low)
1394
		return false;
1395
 
1396
	if (num_pages + kgem->aperture > kgem->aperture_high)
1397
		return false;
1398
 
1399
	if (kgem->nexec + num_exec >= KGEM_EXEC_SIZE(kgem))
1400
		return false;
1401
 
1402
	return true;
1403
}
1404
*/
1405
#if 0
1406
uint32_t kgem_add_reloc(struct kgem *kgem,
1407
            uint32_t pos,
1408
            struct kgem_bo *bo,
1409
            uint32_t read_write_domain,
1410
            uint32_t delta)
1411
{
1412
    int index;
1413
 
1414
	DBG(("%s: handle=%d, pos=%d, delta=%d, domains=%08x\n",
1415
         __FUNCTION__, bo ? bo->handle : 0, pos, delta, read_write_domain));
1416
 
1417
    assert((read_write_domain & 0x7fff) == 0 || bo != NULL);
1418
 
1419
    index = kgem->nreloc++;
1420
    assert(index < ARRAY_SIZE(kgem->reloc));
1421
    kgem->reloc[index].offset = pos * sizeof(kgem->batch[0]);
1422
    if (bo) {
1423
        assert(bo->refcnt);
1424
        assert(!bo->purged);
1425
 
1426
        delta += bo->delta;
1427
        if (bo->proxy) {
1428
            DBG(("%s: adding proxy for handle=%d\n",
1429
                 __FUNCTION__, bo->handle));
1430
            assert(bo->handle == bo->proxy->handle);
1431
            /* need to release the cache upon batch submit */
1432
            list_move(&bo->request, &kgem->next_request->buffers);
1433
            bo->exec = &_kgem_dummy_exec;
1434
            bo = bo->proxy;
1435
        }
1436
 
1437
        assert(!bo->purged);
1438
 
1439
//       if (bo->exec == NULL)
1440
//           _kgem_add_bo(kgem, bo);
1441
 
1442
//        if (kgem->gen < 40 && read_write_domain & KGEM_RELOC_FENCED) {
1443
//            if (bo->tiling &&
1444
//                (bo->exec->flags & EXEC_OBJECT_NEEDS_FENCE) == 0) {
1445
//                assert(kgem->nfence < kgem->fence_max);
1446
//                kgem->aperture_fenced +=
1447
//                    kgem_bo_fenced_size(kgem, bo);
1448
//                kgem->nfence++;
1449
//            }
1450
//            bo->exec->flags |= EXEC_OBJECT_NEEDS_FENCE;
1451
//        }
1452
 
1453
        kgem->reloc[index].delta = delta;
1454
        kgem->reloc[index].target_handle = bo->handle;
1455
        kgem->reloc[index].presumed_offset = bo->presumed_offset;
1456
 
1457
        if (read_write_domain & 0x7fff) {
1458
           DBG(("%s: marking handle=%d dirty\n",
1459
                __FUNCTION__, bo->handle));
1460
           bo->needs_flush = bo->dirty = true;
1461
       }
1462
 
1463
        delta += bo->presumed_offset;
1464
    } else {
1465
        kgem->reloc[index].delta = delta;
1466
        kgem->reloc[index].target_handle = 0;
1467
        kgem->reloc[index].presumed_offset = 0;
1468
    }
1469
    kgem->reloc[index].read_domains = read_write_domain >> 16;
1470
    kgem->reloc[index].write_domain = read_write_domain & 0x7fff;
1471
 
1472
    return delta;
1473
}
1474
#endif
1475
 
1476
 
1477
 
1478
 
1479
 
1480
 
1481
 
1482
 
1483
 
1484
void *kgem_bo_map(struct kgem *kgem, struct kgem_bo *bo)
1485
{
1486
    void *ptr;
1487
 
1488
    DBG(("%s: handle=%d, offset=%d, tiling=%d, map=%p, domain=%d\n", __FUNCTION__,
1489
         bo->handle, bo->presumed_offset, bo->tiling, bo->map, bo->domain));
1490
 
1491
    assert(!bo->purged);
1492
    assert(bo->exec == NULL);
1493
    assert(list_is_empty(&bo->list));
1494
 
1495
//    if (bo->tiling == I915_TILING_NONE &&
1496
//        (kgem->has_llc || bo->domain == bo->presumed_offset)) {
1497
        DBG(("%s: converting request for GTT map into CPU map\n",
1498
             __FUNCTION__));
1499
        ptr = kgem_bo_map__cpu(kgem, bo);
1500
//        kgem_bo_sync__cpu(kgem, bo);
1501
        return ptr;
1502
//    }
1503
 
1504
#if 0
1505
 
1506
    if (IS_CPU_MAP(bo->map))
1507
        kgem_bo_release_map(kgem, bo);
1508
 
1509
    ptr = bo->map;
1510
    if (ptr == NULL) {
1511
        assert(bytes(bo) <= kgem->aperture_mappable / 4);
1512
 
1513
        kgem_trim_vma_cache(kgem, MAP_GTT, bucket(bo));
1514
 
1515
        ptr = gem_mmap(kgem->fd, bo->handle, bytes(bo),
1516
                   PROT_READ | PROT_WRITE);
1517
        if (ptr == NULL)
1518
            return NULL;
1519
 
1520
        /* Cache this mapping to avoid the overhead of an
1521
         * excruciatingly slow GTT pagefault. This is more an
1522
         * issue with compositing managers which need to frequently
1523
         * flush CPU damage to their GPU bo.
1524
         */
1525
        bo->map = ptr;
1526
        DBG(("%s: caching GTT vma for %d\n", __FUNCTION__, bo->handle));
1527
    }
1528
 
1529
    if (bo->domain != DOMAIN_GTT) {
1530
        struct drm_i915_gem_set_domain set_domain;
1531
 
1532
        DBG(("%s: sync: needs_flush? %d, domain? %d\n", __FUNCTION__,
1533
             bo->needs_flush, bo->domain));
1534
 
1535
        /* XXX use PROT_READ to avoid the write flush? */
1536
 
1537
        VG_CLEAR(set_domain);
1538
        set_domain.handle = bo->handle;
1539
        set_domain.read_domains = I915_GEM_DOMAIN_GTT;
1540
        set_domain.write_domain = I915_GEM_DOMAIN_GTT;
1541
        drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain);
1542
 
1543
        kgem_bo_retire(kgem, bo);
1544
        bo->domain = DOMAIN_GTT;
1545
    }
1546
#endif
1547
 
1548
    return ptr;
1549
}
1550
 
1551
void *kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo)
1552
{
1553
//    struct drm_i915_gem_mmap mmap_arg;
1554
 
1555
    DBG(("%s(handle=%d, size=%d)\n", __FUNCTION__, bo->handle, bytes(bo)));
1556
    assert(!bo->purged);
1557
    assert(list_is_empty(&bo->list));
1558
 
1559
    if (IS_CPU_MAP(bo->map))
1560
        return CPU_MAP(bo->map);
1561
 
1562
    struct drm_i915_gem_object *obj = (void*)bo->handle;
1563
    u8    *dst;
1564
    int    ret;
1565
 
1566
    if(obj->pin_count == 0)
1567
    {
1568
        ret = i915_gem_object_pin(obj, 4096, true);
1569
        if (ret)
1570
            return NULL;
1571
    };
1572
 
1573
    dst = drm_intel_bo_map(obj, true);
1574
    DBG(("%s: caching CPU vma for %d\n", __FUNCTION__, bo->handle));
1575
    bo->map = MAKE_CPU_MAP(dst);
1576
    return (void *)dst;
1577
 
1578
 
1579
#if 0
1580
    if (bo->map)
1581
        kgem_bo_release_map(kgem, bo);
1582
 
1583
    kgem_trim_vma_cache(kgem, MAP_CPU, bucket(bo));
1584
 
1585
    VG_CLEAR(mmap_arg);
1586
    mmap_arg.handle = bo->handle;
1587
    mmap_arg.offset = 0;
1588
    mmap_arg.size = bytes(bo);
1589
    if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_MMAP, &mmap_arg)) {
1590
        ErrorF("%s: failed to mmap %d, %d bytes, into CPU domain\n",
1591
               __FUNCTION__, bo->handle, bytes(bo));
1592
        return NULL;
1593
    }
1594
 
1595
    VG(VALGRIND_MALLOCLIKE_BLOCK(mmap_arg.addr_ptr, bytes(bo), 0, 1));
1596
#endif
1597
 
1598
}
1599
 
1600
 
1601
 
1602
 
1603
 
1604
 
1605
 
1606
 
1607
 
1608
 
1609
 
1610
 
1611
 
1612
 
1613
 
1614
 
1615
 
1616
 
1617
 
1618
void kgem_clear_dirty(struct kgem *kgem)
1619
{
1620
    struct kgem_request *rq = kgem->next_request;
1621
    struct kgem_bo *bo;
1622
 
1623
    list_for_each_entry(bo, &rq->buffers, request)
1624
        bo->dirty = false;
1625
}
1626
 
1627
struct kgem_bo *kgem_create_proxy(struct kgem_bo *target,
1628
				  int offset, int length)
1629
{
1630
	struct kgem_bo *bo;
1631
 
1632
	DBG(("%s: target handle=%d, offset=%d, length=%d, io=%d\n",
1633
	     __FUNCTION__, target->handle, offset, length, target->io));
1634
 
1635
	bo = __kgem_bo_alloc(target->handle, length);
1636
	if (bo == NULL)
1637
		return NULL;
1638
 
1639
	bo->reusable = false;
1640
	bo->size.bytes = length;
1641
 
1642
	bo->io = target->io;
1643
	bo->dirty = target->dirty;
1644
	bo->tiling = target->tiling;
1645
	bo->pitch = target->pitch;
1646
 
1647
	if (target->proxy) {
1648
		offset += target->delta;
1649
		target = target->proxy;
1650
	}
1651
	bo->proxy = kgem_bo_reference(target);
1652
	bo->delta = offset;
1653
    bo->gaddr = offset + target->gaddr;
1654
	return bo;
1655
}
1656
 
1657
 
1658
 
1659
 
1660
 
1661
 
1662
 
1663
 
1664
 
1665
 
1666
uint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format)
1667
{
1668
    struct kgem_bo_binding *b;
1669
 
1670
    for (b = &bo->binding; b && b->offset; b = b->next)
1671
        if (format == b->format)
1672
            return b->offset;
1673
 
1674
    return 0;
1675
}
1676
 
1677
void kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset)
1678
{
1679
    struct kgem_bo_binding *b;
1680
 
1681
    for (b = &bo->binding; b; b = b->next) {
1682
        if (b->offset)
1683
            continue;
1684
 
1685
        b->offset = offset;
1686
        b->format = format;
1687
 
1688
        if (b->next)
1689
            b->next->offset = 0;
1690
 
1691
        return;
1692
    }
1693
 
1694
    b = malloc(sizeof(*b));
1695
    if (b) {
1696
        b->next = bo->binding.next;
1697
        b->format = format;
1698
        b->offset = offset;
1699
        bo->binding.next = b;
1700
    }
1701
}
1702
 
1703
 
1704
struct kgem_bo *create_bo(bitmap_t *bitmap)
1705
{
1706
  struct kgem_bo *bo;
1707
 
1708
  bo = __kgem_bo_alloc(bitmap->obj, 1024*768*4/4096);
1709
  bo->gaddr  = bitmap->gaddr;
1710
  bo->pitch  = bitmap->pitch;
1711
  bo->tiling = 0;
1712
  return bo;
1713
 
1714
};