Subversion Repositories Kolibri OS

Rev

Rev 2351 | Go to most recent revision | Details | Compare with Previous | 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
 
2352 Serge 973
int exec_batch(struct drm_device *dev, struct intel_ring_buffer *ring,
974
               batchbuffer_t *exec);
2351 Serge 975
 
2352 Serge 976
void _kgem_submit(struct kgem *kgem, batchbuffer_t *exb)
2351 Serge 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
 
2352 Serge 1023
    exb->batch = kgem->batch_obj;
1024
    exb->exec_start = kgem->batch_obj->gtt_offset+kgem->batch_idx*4096;
1025
    exb->exec_len   = sizeof(uint32_t)*kgem->nbatch;
2351 Serge 1026
 
2352 Serge 1027
    exec_batch(main_device, NULL, exb);
1028
 
2351 Serge 1029
//   if (kgem->wedged)
1030
//       kgem_cleanup(kgem);
1031
 
1032
    kgem->batch_idx++;
1033
    kgem->batch_idx&= 3;
1034
 
1035
	kgem->flush_now = kgem->scanout;
1036
	kgem_reset(kgem);
1037
 
1038
	assert(kgem->next_request != NULL);
1039
}
1040
 
1041
static struct kgem_bo *
1042
search_linear_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags)
1043
{
1044
    struct kgem_bo *bo, *first = NULL;
1045
    bool use_active = (flags & CREATE_INACTIVE) == 0;
1046
    struct list_head *cache;
1047
 
1048
    if (num_pages >= MAX_CACHE_SIZE / PAGE_SIZE)
1049
        return NULL;
1050
 
1051
    if (!use_active &&
1052
        list_is_empty(inactive(kgem, num_pages)) &&
1053
        !list_is_empty(active(kgem, num_pages, I915_TILING_NONE)) &&
1054
        !kgem_retire(kgem))
1055
        return NULL;
1056
 
1057
    if (!use_active && flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
1058
        int for_cpu = !!(flags & CREATE_CPU_MAP);
1059
        cache = &kgem->vma[for_cpu].inactive[cache_bucket(num_pages)];
1060
        list_for_each_entry(bo, cache, vma) {
1061
            assert(IS_CPU_MAP(bo->map) == for_cpu);
1062
            assert(bucket(bo) == cache_bucket(num_pages));
1063
 
1064
            if (num_pages > num_pages(bo)) {
1065
                DBG(("inactive too small: %d < %d\n",
1066
                     num_pages(bo), num_pages));
1067
                continue;
1068
            }
1069
 
1070
            if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
1071
                kgem_bo_free(kgem, bo);
1072
                break;
1073
            }
1074
 
1075
//            if (I915_TILING_NONE != bo->tiling &&
1076
//                gem_set_tiling(kgem->fd, bo->handle,
1077
//                       I915_TILING_NONE, 0) != I915_TILING_NONE)
1078
//                continue;
1079
 
1080
            kgem_bo_remove_from_inactive(kgem, bo);
1081
 
1082
            bo->tiling = I915_TILING_NONE;
1083
            bo->pitch = 0;
1084
            bo->delta = 0;
1085
            DBG(("  %s: found handle=%d (num_pages=%d) in linear vma cache\n",
1086
                 __FUNCTION__, bo->handle, num_pages(bo)));
1087
            assert(use_active || bo->domain != DOMAIN_GPU);
1088
            assert(!bo->needs_flush);
1089
            //assert(!kgem_busy(kgem, bo->handle));
1090
            return bo;
1091
        }
1092
    }
1093
 
1094
    cache = use_active ? active(kgem, num_pages, I915_TILING_NONE) : inactive(kgem, num_pages);
1095
    list_for_each_entry(bo, cache, list) {
1096
        assert(bo->refcnt == 0);
1097
        assert(bo->reusable);
1098
        assert(!!bo->rq == !!use_active);
1099
 
1100
        if (num_pages > num_pages(bo))
1101
            continue;
1102
 
1103
        if (use_active && bo->tiling != I915_TILING_NONE)
1104
            continue;
1105
 
1106
        if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
1107
            kgem_bo_free(kgem, bo);
1108
            break;
1109
        }
1110
/*
1111
        if (I915_TILING_NONE != bo->tiling) {
1112
            if (use_active)
1113
                continue;
1114
 
1115
            if (gem_set_tiling(kgem->fd, bo->handle,
1116
                       I915_TILING_NONE, 0) != I915_TILING_NONE)
1117
                continue;
1118
 
1119
            bo->tiling = I915_TILING_NONE;
1120
        }
1121
*/
1122
        if (bo->map) {
1123
            if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
1124
                int for_cpu = !!(flags & CREATE_CPU_MAP);
1125
                if (IS_CPU_MAP(bo->map) != for_cpu) {
1126
                    if (first != NULL)
1127
                        break;
1128
 
1129
                    first = bo;
1130
                    continue;
1131
                }
1132
            } else {
1133
                if (first != NULL)
1134
                    break;
1135
 
1136
                first = bo;
1137
                continue;
1138
            }
1139
        } else {
1140
            if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
1141
                if (first != NULL)
1142
                    break;
1143
 
1144
                first = bo;
1145
                continue;
1146
            }
1147
        }
1148
 
1149
        if (use_active)
1150
            kgem_bo_remove_from_active(kgem, bo);
1151
        else
1152
            kgem_bo_remove_from_inactive(kgem, bo);
1153
 
1154
        assert(bo->tiling == I915_TILING_NONE);
1155
        bo->pitch = 0;
1156
        bo->delta = 0;
1157
        DBG(("  %s: found handle=%d (num_pages=%d) in linear %s cache\n",
1158
             __FUNCTION__, bo->handle, num_pages(bo),
1159
             use_active ? "active" : "inactive"));
1160
        assert(use_active || bo->domain != DOMAIN_GPU);
1161
        assert(!bo->needs_flush || use_active);
1162
        //assert(use_active || !kgem_busy(kgem, bo->handle));
1163
        return bo;
1164
    }
1165
 
1166
    if (first) {
1167
        assert(first->tiling == I915_TILING_NONE);
1168
 
1169
        if (use_active)
1170
            kgem_bo_remove_from_active(kgem, first);
1171
        else
1172
            kgem_bo_remove_from_inactive(kgem, first);
1173
 
1174
        first->pitch = 0;
1175
        first->delta = 0;
1176
        DBG(("  %s: found handle=%d (num_pages=%d) in linear %s cache\n",
1177
             __FUNCTION__, first->handle, num_pages(first),
1178
             use_active ? "active" : "inactive"));
1179
        assert(use_active || first->domain != DOMAIN_GPU);
1180
        assert(!first->needs_flush || use_active);
1181
        //assert(use_active || !kgem_busy(kgem, first->handle));
1182
        return first;
1183
    }
1184
 
1185
    return NULL;
1186
}
1187
 
1188
 
1189
 
1190
 
1191
 
1192
 
1193
struct kgem_bo *kgem_create_linear(struct kgem *kgem, int size)
1194
{
1195
    struct kgem_bo *bo;
1196
    uint32_t handle;
1197
 
1198
    DBG(("%s(%d)\n", __FUNCTION__, size));
1199
 
1200
    size = (size + PAGE_SIZE - 1) / PAGE_SIZE;
1201
    bo = search_linear_cache(kgem, size, CREATE_INACTIVE);
1202
    if (bo)
1203
        return kgem_bo_reference(bo);
1204
 
1205
    handle = gem_create(kgem->fd, size);
1206
    if (handle == 0)
1207
        return NULL;
1208
 
1209
    DBG(("%s: new handle=%x\n", __FUNCTION__, handle));
1210
    bo = __kgem_bo_alloc(handle, size);
1211
    if (bo == NULL) {
1212
        gem_close(kgem->fd, handle);
1213
        return NULL;
1214
    }
1215
    struct drm_i915_gem_object *obj;
1216
    obj = (void*)handle;
1217
 
1218
    bo->gaddr = obj->gtt_offset;
1219
    return bo;
1220
}
1221
 
1222
 
1223
 
1224
 
1225
 
1226
 
1227
inline int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo)
1228
{
1229
	unsigned int size;
1230
 
1231
	assert(bo->tiling);
1232
	assert(kgem->gen < 40);
1233
 
1234
	if (kgem->gen < 30)
1235
		size = 512 * 1024;
1236
	else
1237
		size = 1024 * 1024;
1238
	while (size < bytes(bo))
1239
		size *= 2;
1240
 
1241
	return size;
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
 
1288
 
1289
 
1290
 
1291
void _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
1292
{
1293
//    if (bo->proxy) {
1294
//        assert(bo->map == NULL);
1295
//        if (bo->io && bo->exec == NULL)
1296
//            _kgem_bo_delete_partial(kgem, bo);
1297
//        kgem_bo_unref(kgem, bo->proxy);
1298
//        kgem_bo_binding_free(kgem, bo);
1299
//        _list_del(&bo->request);
1300
//        free(bo);
1301
//        return;
1302
//    }
1303
 
1304
//    if (bo->vmap)
1305
//        kgem_bo_sync__cpu(kgem, bo);
1306
 
1307
    __kgem_bo_destroy(kgem, bo);
1308
}
1309
 
1310
void __kgem_flush(struct kgem *kgem, struct kgem_bo *bo)
1311
{
1312
	/* The kernel will emit a flush *and* update its own flushing lists. */
1313
//	kgem_busy(kgem, bo->handle);
1314
}
1315
 
1316
bool kgem_check_bo(struct kgem *kgem, ...)
1317
{
1318
    va_list ap;
1319
    struct kgem_bo *bo;
1320
    int num_exec = 0;
1321
    int num_pages = 0;
1322
 
1323
    va_start(ap, kgem);
1324
    while ((bo = va_arg(ap, struct kgem_bo *))) {
1325
        if (bo->exec)
1326
            continue;
1327
 
1328
        if (bo->proxy) {
1329
            bo = bo->proxy;
1330
            if (bo->exec)
1331
                continue;
1332
        }
1333
        num_pages += num_pages(bo);
1334
        num_exec++;
1335
    }
1336
    va_end(ap);
1337
 
1338
    if (!num_pages)
1339
        return true;
1340
 
1341
    if (kgem->aperture > kgem->aperture_low)
1342
        return false;
1343
 
1344
    if (num_pages + kgem->aperture > kgem->aperture_high)
1345
        return false;
1346
 
1347
    if (kgem->nexec + num_exec >= KGEM_EXEC_SIZE(kgem))
1348
        return false;
1349
 
1350
    return true;
1351
}
1352
 
1353
/*
1354
bool kgem_check_bo_fenced(struct kgem *kgem, ...)
1355
{
1356
	va_list ap;
1357
	struct kgem_bo *bo;
1358
	int num_fence = 0;
1359
	int num_exec = 0;
1360
	int num_pages = 0;
1361
	int fenced_size = 0;
1362
 
1363
	va_start(ap, kgem);
1364
	while ((bo = va_arg(ap, struct kgem_bo *))) {
1365
		if (bo->proxy)
1366
			bo = bo->proxy;
1367
		if (bo->exec) {
1368
			if (kgem->gen >= 40 || bo->tiling == I915_TILING_NONE)
1369
				continue;
1370
 
1371
			if ((bo->exec->flags & EXEC_OBJECT_NEEDS_FENCE) == 0) {
1372
				fenced_size += kgem_bo_fenced_size(kgem, bo);
1373
				num_fence++;
1374
			}
1375
 
1376
			continue;
1377
		}
1378
 
1379
		num_pages += num_pages(bo);
1380
		num_exec++;
1381
		if (kgem->gen < 40 && bo->tiling) {
1382
			fenced_size += kgem_bo_fenced_size(kgem, bo);
1383
			num_fence++;
1384
		}
1385
	}
1386
	va_end(ap);
1387
 
1388
	if (fenced_size + kgem->aperture_fenced > kgem->aperture_mappable)
1389
		return false;
1390
 
1391
	if (kgem->nfence + num_fence > kgem->fence_max)
1392
		return false;
1393
 
1394
	if (!num_pages)
1395
		return true;
1396
 
1397
	if (kgem->aperture > kgem->aperture_low)
1398
		return false;
1399
 
1400
	if (num_pages + kgem->aperture > kgem->aperture_high)
1401
		return false;
1402
 
1403
	if (kgem->nexec + num_exec >= KGEM_EXEC_SIZE(kgem))
1404
		return false;
1405
 
1406
	return true;
1407
}
1408
*/
1409
#if 0
1410
uint32_t kgem_add_reloc(struct kgem *kgem,
1411
            uint32_t pos,
1412
            struct kgem_bo *bo,
1413
            uint32_t read_write_domain,
1414
            uint32_t delta)
1415
{
1416
    int index;
1417
 
1418
	DBG(("%s: handle=%d, pos=%d, delta=%d, domains=%08x\n",
1419
         __FUNCTION__, bo ? bo->handle : 0, pos, delta, read_write_domain));
1420
 
1421
    assert((read_write_domain & 0x7fff) == 0 || bo != NULL);
1422
 
1423
    index = kgem->nreloc++;
1424
    assert(index < ARRAY_SIZE(kgem->reloc));
1425
    kgem->reloc[index].offset = pos * sizeof(kgem->batch[0]);
1426
    if (bo) {
1427
        assert(bo->refcnt);
1428
        assert(!bo->purged);
1429
 
1430
        delta += bo->delta;
1431
        if (bo->proxy) {
1432
            DBG(("%s: adding proxy for handle=%d\n",
1433
                 __FUNCTION__, bo->handle));
1434
            assert(bo->handle == bo->proxy->handle);
1435
            /* need to release the cache upon batch submit */
1436
            list_move(&bo->request, &kgem->next_request->buffers);
1437
            bo->exec = &_kgem_dummy_exec;
1438
            bo = bo->proxy;
1439
        }
1440
 
1441
        assert(!bo->purged);
1442
 
1443
//       if (bo->exec == NULL)
1444
//           _kgem_add_bo(kgem, bo);
1445
 
1446
//        if (kgem->gen < 40 && read_write_domain & KGEM_RELOC_FENCED) {
1447
//            if (bo->tiling &&
1448
//                (bo->exec->flags & EXEC_OBJECT_NEEDS_FENCE) == 0) {
1449
//                assert(kgem->nfence < kgem->fence_max);
1450
//                kgem->aperture_fenced +=
1451
//                    kgem_bo_fenced_size(kgem, bo);
1452
//                kgem->nfence++;
1453
//            }
1454
//            bo->exec->flags |= EXEC_OBJECT_NEEDS_FENCE;
1455
//        }
1456
 
1457
        kgem->reloc[index].delta = delta;
1458
        kgem->reloc[index].target_handle = bo->handle;
1459
        kgem->reloc[index].presumed_offset = bo->presumed_offset;
1460
 
1461
        if (read_write_domain & 0x7fff) {
1462
           DBG(("%s: marking handle=%d dirty\n",
1463
                __FUNCTION__, bo->handle));
1464
           bo->needs_flush = bo->dirty = true;
1465
       }
1466
 
1467
        delta += bo->presumed_offset;
1468
    } else {
1469
        kgem->reloc[index].delta = delta;
1470
        kgem->reloc[index].target_handle = 0;
1471
        kgem->reloc[index].presumed_offset = 0;
1472
    }
1473
    kgem->reloc[index].read_domains = read_write_domain >> 16;
1474
    kgem->reloc[index].write_domain = read_write_domain & 0x7fff;
1475
 
1476
    return delta;
1477
}
1478
#endif
1479
 
1480
 
1481
 
1482
 
1483
 
1484
 
1485
 
1486
 
1487
 
1488
void *kgem_bo_map(struct kgem *kgem, struct kgem_bo *bo)
1489
{
1490
    void *ptr;
1491
 
1492
    DBG(("%s: handle=%d, offset=%d, tiling=%d, map=%p, domain=%d\n", __FUNCTION__,
1493
         bo->handle, bo->presumed_offset, bo->tiling, bo->map, bo->domain));
1494
 
1495
    assert(!bo->purged);
1496
    assert(bo->exec == NULL);
1497
    assert(list_is_empty(&bo->list));
1498
 
1499
//    if (bo->tiling == I915_TILING_NONE &&
1500
//        (kgem->has_llc || bo->domain == bo->presumed_offset)) {
1501
        DBG(("%s: converting request for GTT map into CPU map\n",
1502
             __FUNCTION__));
1503
        ptr = kgem_bo_map__cpu(kgem, bo);
1504
//        kgem_bo_sync__cpu(kgem, bo);
1505
        return ptr;
1506
//    }
1507
 
1508
#if 0
1509
 
1510
    if (IS_CPU_MAP(bo->map))
1511
        kgem_bo_release_map(kgem, bo);
1512
 
1513
    ptr = bo->map;
1514
    if (ptr == NULL) {
1515
        assert(bytes(bo) <= kgem->aperture_mappable / 4);
1516
 
1517
        kgem_trim_vma_cache(kgem, MAP_GTT, bucket(bo));
1518
 
1519
        ptr = gem_mmap(kgem->fd, bo->handle, bytes(bo),
1520
                   PROT_READ | PROT_WRITE);
1521
        if (ptr == NULL)
1522
            return NULL;
1523
 
1524
        /* Cache this mapping to avoid the overhead of an
1525
         * excruciatingly slow GTT pagefault. This is more an
1526
         * issue with compositing managers which need to frequently
1527
         * flush CPU damage to their GPU bo.
1528
         */
1529
        bo->map = ptr;
1530
        DBG(("%s: caching GTT vma for %d\n", __FUNCTION__, bo->handle));
1531
    }
1532
 
1533
    if (bo->domain != DOMAIN_GTT) {
1534
        struct drm_i915_gem_set_domain set_domain;
1535
 
1536
        DBG(("%s: sync: needs_flush? %d, domain? %d\n", __FUNCTION__,
1537
             bo->needs_flush, bo->domain));
1538
 
1539
        /* XXX use PROT_READ to avoid the write flush? */
1540
 
1541
        VG_CLEAR(set_domain);
1542
        set_domain.handle = bo->handle;
1543
        set_domain.read_domains = I915_GEM_DOMAIN_GTT;
1544
        set_domain.write_domain = I915_GEM_DOMAIN_GTT;
1545
        drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain);
1546
 
1547
        kgem_bo_retire(kgem, bo);
1548
        bo->domain = DOMAIN_GTT;
1549
    }
1550
#endif
1551
 
1552
    return ptr;
1553
}
1554
 
1555
void *kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo)
1556
{
1557
//    struct drm_i915_gem_mmap mmap_arg;
1558
 
1559
    DBG(("%s(handle=%d, size=%d)\n", __FUNCTION__, bo->handle, bytes(bo)));
1560
    assert(!bo->purged);
1561
    assert(list_is_empty(&bo->list));
1562
 
1563
    if (IS_CPU_MAP(bo->map))
1564
        return CPU_MAP(bo->map);
1565
 
1566
    struct drm_i915_gem_object *obj = (void*)bo->handle;
1567
    u8    *dst;
1568
    int    ret;
1569
 
1570
    if(obj->pin_count == 0)
1571
    {
1572
        ret = i915_gem_object_pin(obj, 4096, true);
1573
        if (ret)
1574
            return NULL;
1575
    };
1576
 
1577
    dst = drm_intel_bo_map(obj, true);
1578
    DBG(("%s: caching CPU vma for %d\n", __FUNCTION__, bo->handle));
1579
    bo->map = MAKE_CPU_MAP(dst);
1580
    return (void *)dst;
1581
 
1582
 
1583
#if 0
1584
    if (bo->map)
1585
        kgem_bo_release_map(kgem, bo);
1586
 
1587
    kgem_trim_vma_cache(kgem, MAP_CPU, bucket(bo));
1588
 
1589
    VG_CLEAR(mmap_arg);
1590
    mmap_arg.handle = bo->handle;
1591
    mmap_arg.offset = 0;
1592
    mmap_arg.size = bytes(bo);
1593
    if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_MMAP, &mmap_arg)) {
1594
        ErrorF("%s: failed to mmap %d, %d bytes, into CPU domain\n",
1595
               __FUNCTION__, bo->handle, bytes(bo));
1596
        return NULL;
1597
    }
1598
 
1599
    VG(VALGRIND_MALLOCLIKE_BLOCK(mmap_arg.addr_ptr, bytes(bo), 0, 1));
1600
#endif
1601
 
1602
}
1603
 
1604
 
1605
 
1606
 
1607
 
1608
 
1609
 
1610
 
1611
 
1612
 
1613
 
1614
 
1615
 
1616
 
1617
 
1618
 
1619
 
1620
 
1621
 
1622
void kgem_clear_dirty(struct kgem *kgem)
1623
{
1624
    struct kgem_request *rq = kgem->next_request;
1625
    struct kgem_bo *bo;
1626
 
1627
    list_for_each_entry(bo, &rq->buffers, request)
1628
        bo->dirty = false;
1629
}
1630
 
1631
struct kgem_bo *kgem_create_proxy(struct kgem_bo *target,
1632
				  int offset, int length)
1633
{
1634
	struct kgem_bo *bo;
1635
 
1636
	DBG(("%s: target handle=%d, offset=%d, length=%d, io=%d\n",
1637
	     __FUNCTION__, target->handle, offset, length, target->io));
1638
 
1639
	bo = __kgem_bo_alloc(target->handle, length);
1640
	if (bo == NULL)
1641
		return NULL;
1642
 
1643
	bo->reusable = false;
1644
	bo->size.bytes = length;
1645
 
1646
	bo->io = target->io;
1647
	bo->dirty = target->dirty;
1648
	bo->tiling = target->tiling;
1649
	bo->pitch = target->pitch;
1650
 
1651
	if (target->proxy) {
1652
		offset += target->delta;
1653
		target = target->proxy;
1654
	}
1655
	bo->proxy = kgem_bo_reference(target);
1656
	bo->delta = offset;
1657
    bo->gaddr = offset + target->gaddr;
1658
	return bo;
1659
}
1660
 
1661
 
1662
 
1663
 
1664
 
1665
 
1666
 
1667
 
1668
 
1669
 
1670
uint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format)
1671
{
1672
    struct kgem_bo_binding *b;
1673
 
1674
    for (b = &bo->binding; b && b->offset; b = b->next)
1675
        if (format == b->format)
1676
            return b->offset;
1677
 
1678
    return 0;
1679
}
1680
 
1681
void kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset)
1682
{
1683
    struct kgem_bo_binding *b;
1684
 
1685
    for (b = &bo->binding; b; b = b->next) {
1686
        if (b->offset)
1687
            continue;
1688
 
1689
        b->offset = offset;
1690
        b->format = format;
1691
 
1692
        if (b->next)
1693
            b->next->offset = 0;
1694
 
1695
        return;
1696
    }
1697
 
1698
    b = malloc(sizeof(*b));
1699
    if (b) {
1700
        b->next = bo->binding.next;
1701
        b->format = format;
1702
        b->offset = offset;
1703
        bo->binding.next = b;
1704
    }
1705
}
1706
 
1707
 
1708
struct kgem_bo *create_bo(bitmap_t *bitmap)
1709
{
1710
  struct kgem_bo *bo;
1711
 
1712
  bo = __kgem_bo_alloc(bitmap->obj, 1024*768*4/4096);
1713
  bo->gaddr  = bitmap->gaddr;
1714
  bo->pitch  = bitmap->pitch;
1715
  bo->tiling = 0;
1716
  return bo;
1717
 
1718
};