Subversion Repositories Kolibri OS

Rev

Rev 4245 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4245 Rev 4251
Line 26... Line 26...
26
 */
26
 */
Line 27... Line 27...
27
 
27
 
28
#ifndef KGEM_H
28
#ifndef KGEM_H
Line 29... Line -...
29
#define KGEM_H
-
 
30
 
-
 
31
#define HAS_DEBUG_FULL 1
29
#define KGEM_H
-
 
30
 
32
 
31
#include 
33
#include 
32
#include 
34
#include 
-
 
Line 35... Line 33...
35
#include 
33
#include 
Line 36... Line 34...
36
#include 
34
#include 
37
 
35
 
Line -... Line 36...
-
 
36
#include 
-
 
37
 
-
 
38
#include "compiler.h"
-
 
39
#include "intel_list.h"
-
 
40
 
-
 
41
#include 
-
 
42
#if !defined(MAXSHORT) || !defined(MINSHORT) || \
-
 
43
    !defined(MAXINT) || !defined(MININT)
-
 
44
/*
-
 
45
 * Some implementations #define these through , so preclude
-
 
46
 * #include'ing it later.
-
 
47
 */
-
 
48
 
38
#include 
49
#include 
-
 
50
#undef MAXSHORT
-
 
51
#define MAXSHORT SHRT_MAX
-
 
52
#undef MINSHORT
Line 39... Line -...
39
 
-
 
40
#include "compiler.h"
-
 
41
#include "intel_list.h"
-
 
42
 
-
 
43
#undef  DBG
53
#define MINSHORT SHRT_MIN
Line 44... Line 54...
44
 
54
#undef MAXINT
45
#if HAS_DEBUG_FULL
55
#define MAXINT INT_MAX
46
#define DBG(x) printf x
56
#undef MININT
Line 62... Line 72...
62
	struct list vma;
72
	struct list vma;
Line 63... Line 73...
63
 
73
 
64
    void     *map;
74
    void     *map;
65
#define IS_CPU_MAP(ptr) ((uintptr_t)(ptr) & 1)
75
#define IS_CPU_MAP(ptr) ((uintptr_t)(ptr) & 1)
-
 
76
#define IS_GTT_MAP(ptr) (ptr && ((uintptr_t)(ptr) & 1) == 0)
Line 66... Line 77...
66
#define IS_GTT_MAP(ptr) (ptr && ((uintptr_t)(ptr) & 1) == 0)
77
#define MAP(ptr) ((void*)((uintptr_t)(ptr) & ~3))
67
 
78
 
68
	struct kgem_bo_binding {
79
	struct kgem_bo_binding {
69
		struct kgem_bo_binding *next;
80
		struct kgem_bo_binding *next;
Line 88... Line 99...
88
		uint32_t bytes;
99
		uint32_t bytes;
89
	} size;
100
	} size;
90
    uint32_t pitch  : 18; /* max 128k */
101
    uint32_t pitch  : 18; /* max 128k */
91
	uint32_t tiling : 2;
102
	uint32_t tiling : 2;
92
	uint32_t reusable : 1;
103
	uint32_t reusable : 1;
-
 
104
	uint32_t gpu_dirty : 1;
93
    uint32_t dirty  : 1;
105
	uint32_t gtt_dirty : 1;
94
	uint32_t domain : 2;
106
	uint32_t domain : 2;
95
	uint32_t needs_flush : 1;
107
	uint32_t needs_flush : 1;
96
	uint32_t snoop : 1;
108
	uint32_t snoop : 1;
97
    uint32_t io     : 1;
109
    uint32_t io     : 1;
98
    uint32_t flush  : 1;
110
    uint32_t flush  : 1;
Line 171... Line 183...
171
	uint32_t need_retire:1;
183
	uint32_t need_retire:1;
172
	uint32_t need_throttle:1;
184
	uint32_t need_throttle:1;
173
	uint32_t scanout_busy:1;
185
	uint32_t scanout_busy:1;
174
	uint32_t busy:1;
186
	uint32_t busy:1;
Line -... Line 187...
-
 
187
 
175
 
188
	uint32_t has_create2 :1;
176
	uint32_t has_userptr :1;
189
	uint32_t has_userptr :1;
177
	uint32_t has_blt :1;
190
	uint32_t has_blt :1;
178
	uint32_t has_relaxed_fencing :1;
191
	uint32_t has_relaxed_fencing :1;
179
	uint32_t has_relaxed_delta :1;
192
	uint32_t has_relaxed_delta :1;
180
	uint32_t has_semaphores :1;
193
	uint32_t has_semaphores :1;
181
	uint32_t has_secure_batches :1;
194
	uint32_t has_secure_batches :1;
182
	uint32_t has_pinned_batches :1;
195
	uint32_t has_pinned_batches :1;
183
	uint32_t has_cacheing :1;
196
	uint32_t has_caching :1;
-
 
197
	uint32_t has_llc :1;
184
	uint32_t has_llc :1;
198
	uint32_t has_wt :1;
185
	uint32_t has_no_reloc :1;
199
	uint32_t has_no_reloc :1;
Line 186... Line 200...
186
	uint32_t has_handle_lut :1;
200
	uint32_t has_handle_lut :1;
Line 198... Line 212...
198
 
212
 
199
	void (*context_switch)(struct kgem *kgem, int new_mode);
213
	void (*context_switch)(struct kgem *kgem, int new_mode);
200
    void (*retire)(struct kgem *kgem);
214
    void (*retire)(struct kgem *kgem);
Line -... Line 215...
-
 
215
	void (*expire)(struct kgem *kgem);
-
 
216
 
-
 
217
#if 0
-
 
218
	void (*memcpy_to_tiled_x)(const void *src, void *dst, int bpp,
201
	void (*expire)(struct kgem *kgem);
219
				  int32_t src_stride, int32_t dst_stride,
-
 
220
				  int16_t src_x, int16_t src_y,
-
 
221
				  int16_t dst_x, int16_t dst_y,
-
 
222
				  uint16_t width, uint16_t height);
202
 
223
	void (*memcpy_from_tiled_x)(const void *src, void *dst, int bpp,
-
 
224
				    int32_t src_stride, int32_t dst_stride,
203
	uint32_t batch[64*1024-8];
225
				    int16_t src_x, int16_t src_y,
-
 
226
				    int16_t dst_x, int16_t dst_y,
-
 
227
				    uint16_t width, uint16_t height);
204
	struct drm_i915_gem_exec_object2 exec[256];
228
#endif
-
 
229
 
-
 
230
	uint16_t reloc__self[256];
-
 
231
	uint32_t batch[64*1024-8] page_aligned;
Line 205... Line 232...
205
	struct drm_i915_gem_relocation_entry reloc[4096];
232
	struct drm_i915_gem_exec_object2 exec[384] page_aligned;
206
	uint16_t reloc__self[256];
233
	struct drm_i915_gem_relocation_entry reloc[8192] page_aligned;
207
 
234
 
208
#ifdef DEBUG_MEMORY
235
#ifdef DEBUG_MEMORY
209
	struct {
236
	struct {
210
		int bo_allocs;
237
		int bo_allocs;
211
		size_t bo_bytes;
238
		size_t bo_bytes;
Line -... Line 239...
-
 
239
	} debug_memory;
-
 
240
#endif
212
	} debug_memory;
241
};
213
#endif
242
 
214
};
243
#define KGEM_MAX_DEFERRED_VBO 16
Line 215... Line 244...
215
 
244
 
216
#define KGEM_BATCH_RESERVED 1
245
#define KGEM_BATCH_RESERVED 1
217
#define KGEM_RELOC_RESERVED 4
246
#define KGEM_RELOC_RESERVED (KGEM_MAX_DEFERRED_VBO)
Line 231... Line 260...
231
struct kgem_bo *kgem_create_map(struct kgem *kgem,
260
struct kgem_bo *kgem_create_map(struct kgem *kgem,
232
				void *ptr, uint32_t size,
261
				void *ptr, uint32_t size,
233
				bool read_only);
262
				bool read_only);
Line 234... Line 263...
234
 
263
 
-
 
264
struct kgem_bo *kgem_create_for_name(struct kgem *kgem, uint32_t name);
-
 
265
struct kgem_bo *kgem_create_for_prime(struct kgem *kgem, int name, uint32_t size);
Line 235... Line 266...
235
struct kgem_bo *kgem_create_for_name(struct kgem *kgem, uint32_t name);
266
int kgem_bo_export_to_prime(struct kgem *kgem, struct kgem_bo *bo);
236
 
267
 
237
struct kgem_bo *kgem_create_linear(struct kgem *kgem, int size, unsigned flags);
268
struct kgem_bo *kgem_create_linear(struct kgem *kgem, int size, unsigned flags);
238
struct kgem_bo *kgem_create_proxy(struct kgem *kgem,
269
struct kgem_bo *kgem_create_proxy(struct kgem *kgem,
Line -... Line 270...
-
 
270
				  struct kgem_bo *target,
Line 239... Line 271...
239
				  struct kgem_bo *target,
271
				  int offset, int length);
240
				  int offset, int length);
272
 
241
 
273
void kgem_proxy_bo_attach(struct kgem_bo *bo, struct kgem_bo **ptr);
242
 
274
 
243
int kgem_choose_tiling(struct kgem *kgem,
275
int kgem_choose_tiling(struct kgem *kgem,
244
		       int tiling, int width, int height, int bpp);
276
		       int tiling, int width, int height, int bpp);
245
unsigned kgem_can_create_2d(struct kgem *kgem, int width, int height, int depth);
277
unsigned kgem_can_create_2d(struct kgem *kgem, int width, int height, int depth);
Line -... Line 278...
-
 
278
#define KGEM_CAN_CREATE_GPU     0x1
-
 
279
#define KGEM_CAN_CREATE_CPU     0x2
246
#define KGEM_CAN_CREATE_GPU     0x1
280
#define KGEM_CAN_CREATE_LARGE	0x4
247
#define KGEM_CAN_CREATE_CPU     0x2
281
#define KGEM_CAN_CREATE_GTT	0x8
248
#define KGEM_CAN_CREATE_LARGE	0x4
282
 
249
#define KGEM_CAN_CREATE_GTT	0x8
283
uint32_t kgem_get_unique_id(struct kgem *kgem);
250
 
284
 
Line 279... Line 313...
279
				   int bpp,
313
				   int bpp,
280
				   uint32_t flags);
314
				   uint32_t flags);
Line 281... Line 315...
281
 
315
 
282
uint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format);
316
uint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format);
283
void kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset);
-
 
Line 284... Line 317...
284
int kgem_bo_get_swizzling(struct kgem *kgem, struct kgem_bo *bo);
317
void kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset);
Line 285... Line 318...
285
 
318
 
286
bool kgem_retire(struct kgem *kgem);
319
bool kgem_retire(struct kgem *kgem);
Line 302... Line 335...
302
		return true;
335
		return true;
Line 303... Line 336...
303
 
336
 
304
	return kgem_ring_is_idle(kgem, kgem->ring);
337
	return kgem_ring_is_idle(kgem, kgem->ring);
Line -... Line 338...
-
 
338
}
-
 
339
 
-
 
340
static inline bool __kgem_ring_empty(struct kgem *kgem)
-
 
341
{
-
 
342
	return list_is_empty(&kgem->requests[kgem->ring == KGEM_BLT]);
305
}
343
}
306
 
344
 
307
void _kgem_submit(struct kgem *kgem);
345
void _kgem_submit(struct kgem *kgem);
308
static inline void kgem_submit(struct kgem *kgem)
346
static inline void kgem_submit(struct kgem *kgem)
309
{
347
{
Line 323... Line 361...
323
{
361
{
324
	if (bo->exec)
362
	if (bo->exec)
325
		_kgem_submit(kgem);
363
		_kgem_submit(kgem);
326
}
364
}
Line 327... Line 365...
327
 
365
 
328
void __kgem_flush(struct kgem *kgem, struct kgem_bo *bo);
-
 
329
static inline void kgem_bo_flush(struct kgem *kgem, struct kgem_bo *bo)
-
 
330
{
-
 
331
	kgem_bo_submit(kgem, bo);
-
 
332
 
-
 
333
	if (!bo->needs_flush)
-
 
334
		return;
-
 
335
 
-
 
336
	/* If the kernel fails to emit the flush, then it will be forced when
-
 
337
	 * we assume direct access. And as the useual failure is EIO, we do
-
 
338
	 * not actualy care.
-
 
339
	 */
-
 
340
	__kgem_flush(kgem, bo);
-
 
Line 341... Line 366...
341
}
366
void kgem_scanout_flush(struct kgem *kgem, struct kgem_bo *bo);
342
 
367
 
343
static inline struct kgem_bo *kgem_bo_reference(struct kgem_bo *bo)
368
static inline struct kgem_bo *kgem_bo_reference(struct kgem_bo *bo)
344
{
369
{
Line 365... Line 390...
365
 
390
 
366
#if DEBUG_FLUSH_BATCH
391
#if DEBUG_FLUSH_BATCH
367
	kgem_submit(kgem);
392
	kgem_submit(kgem);
Line -... Line 393...
-
 
393
#endif
-
 
394
 
-
 
395
	if (kgem->nreloc && bo->exec == NULL && kgem_ring_is_idle(kgem, kgem->ring))
368
#endif
396
		_kgem_submit(kgem);
369
 
397
 
Line 370... Line 398...
370
	if (kgem->mode == mode)
398
	if (kgem->mode == mode)
371
		return;
399
		return;
Line 417... Line 445...
417
		kgem_check_exec(kgem, num_surfaces);
445
		kgem_check_exec(kgem, num_surfaces);
418
}
446
}
Line 419... Line 447...
419
 
447
 
420
static inline uint32_t *kgem_get_batch(struct kgem *kgem)
448
static inline uint32_t *kgem_get_batch(struct kgem *kgem)
-
 
449
{
-
 
450
	if (kgem->nreloc) {
-
 
451
		unsigned mode = kgem->mode;
-
 
452
		_kgem_submit(kgem);
-
 
453
		_kgem_set_mode(kgem, mode);
Line 421... Line 454...
421
{
454
	}
422
 
455
 
Line 423... Line 456...
423
	return kgem->batch + kgem->nbatch;
456
	return kgem->batch + kgem->nbatch;
Line 510... Line 543...
510
 
543
 
511
	if (kgem->gen < 040 && bo->tiling &&
544
	if (kgem->gen < 040 && bo->tiling &&
512
	    bo->presumed_offset & (kgem_bo_fenced_size(kgem, bo) - 1))
545
	    bo->presumed_offset & (kgem_bo_fenced_size(kgem, bo) - 1))
Line -... Line 546...
-
 
546
		return false;
-
 
547
 
-
 
548
	if (kgem->gen == 021 && bo->tiling == I915_TILING_Y)
-
 
549
		return false;
-
 
550
 
-
 
551
	if (kgem->has_llc && bo->tiling == I915_TILING_NONE)
513
		return false;
552
		return true;
514
 
553
 
Line 515... Line 554...
515
	if (!bo->presumed_offset)
554
	if (!bo->presumed_offset)
516
		return kgem_bo_size(bo) <= kgem->aperture_mappable / 4;
555
		return kgem_bo_size(bo) <= kgem->aperture_mappable / 4;
Line 542... Line 581...
542
static inline bool kgem_bo_can_map(struct kgem *kgem, struct kgem_bo *bo)
581
static inline bool kgem_bo_can_map(struct kgem *kgem, struct kgem_bo *bo)
543
{
582
{
544
	if (kgem_bo_mapped(kgem, bo))
583
	if (kgem_bo_mapped(kgem, bo))
545
		return true;
584
		return true;
Line 546... Line 585...
546
 
585
 
547
	if (!bo->tiling && kgem->has_llc)
586
	if (!bo->tiling && (kgem->has_llc || bo->domain == DOMAIN_CPU))
Line 548... Line 587...
548
		return true;
587
		return true;
549
 
588
 
Line 550... Line 589...
550
	if (kgem->gen == 021 && bo->tiling == I915_TILING_Y)
589
	if (kgem->gen == 021 && bo->tiling == I915_TILING_Y)
551
		return false;
590
		return false;
Line -... Line 591...
-
 
591
 
-
 
592
	return kgem_bo_size(bo) <= kgem->aperture_mappable / 4;
-
 
593
}
-
 
594
 
-
 
595
static inline bool kgem_bo_can_map__cpu(struct kgem *kgem,
-
 
596
					struct kgem_bo *bo,
-
 
597
					bool write)
-
 
598
{
-
 
599
	if (bo->purged || (bo->scanout && write))
-
 
600
		return false;
-
 
601
 
-
 
602
	if (kgem->has_llc)
-
 
603
		return true;
-
 
604
 
-
 
605
	if (bo->domain != DOMAIN_CPU)
-
 
606
		return false;
552
 
607
 
553
	return kgem_bo_size(bo) <= kgem->aperture_mappable / 4;
608
	return !write || bo->exec == NULL;
554
}
609
}
555
 
610
 
556
static inline bool kgem_bo_is_snoop(struct kgem_bo *bo)
611
static inline bool kgem_bo_is_snoop(struct kgem_bo *bo)
557
{
612
{
558
	assert(bo->refcnt);
613
	assert(bo->refcnt);
Line -... Line 614...
-
 
614
	while (bo->proxy)
-
 
615
		bo = bo->proxy;
559
	while (bo->proxy)
616
	return bo->snoop;
Line 560... Line 617...
560
		bo = bo->proxy;
617
}
561
	return bo->snoop;
618
 
562
}
619
void kgem_bo_undo(struct kgem *kgem, struct kgem_bo *bo);
563
 
620
 
Line 564... Line 621...
564
bool __kgem_busy(struct kgem *kgem, int handle);
621
bool __kgem_busy(struct kgem *kgem, int handle);
565
 
622
 
566
static inline void kgem_bo_mark_busy(struct kgem_bo *bo, int ring)
-
 
567
{
-
 
568
	bo->rq = (struct kgem_request *)((uintptr_t)bo->rq | ring);
623
static inline void kgem_bo_mark_busy(struct kgem_bo *bo, int ring)
-
 
624
{
-
 
625
	bo->rq = (struct kgem_request *)((uintptr_t)bo->rq | ring);
569
}
626
}
-
 
627
 
-
 
628
inline static void __kgem_bo_clear_busy(struct kgem_bo *bo)
570
 
629
{
Line 571... Line 630...
571
inline static void __kgem_bo_clear_busy(struct kgem_bo *bo)
630
	bo->rq = NULL;
572
{
631
	list_del(&bo->request);
573
	bo->needs_flush = false;
632
 
574
	list_del(&bo->request);
633
	bo->domain = DOMAIN_NONE;
575
	bo->rq = NULL;
634
	bo->needs_flush = false;
576
	bo->domain = DOMAIN_NONE;
635
	bo->gtt_dirty = false;
577
}
636
}
Line 578... Line -...
578
 
-
 
579
static inline bool kgem_bo_is_busy(struct kgem_bo *bo)
-
 
580
{
637
 
581
	DBG(("%s: handle=%d, domain: %d exec? %d, rq? %d\n", __FUNCTION__,
638
static inline bool kgem_bo_is_busy(struct kgem_bo *bo)
582
	     bo->handle, bo->domain, bo->exec != NULL, bo->rq != NULL));
639
{
583
	assert(bo->refcnt);
640
	DBG(("%s: handle=%d, domain: %d exec? %d, rq? %d\n", __FUNCTION__,
584
	return bo->rq;
641
	     bo->handle, bo->domain, bo->exec != NULL, bo->rq != NULL));
Line 602... Line 659...
602
		__kgem_bo_clear_busy(bo);
659
		__kgem_bo_clear_busy(bo);
Line 603... Line 660...
603
 
660
 
604
	return kgem_bo_is_busy(bo);
661
	return kgem_bo_is_busy(bo);
Line -... Line 662...
-
 
662
}
-
 
663
 
-
 
664
static inline bool kgem_bo_is_render(struct kgem_bo *bo)
-
 
665
{
-
 
666
	DBG(("%s: handle=%d, rq? %d [%d]\n", __FUNCTION__,
-
 
667
	     bo->handle, bo->rq != NULL, (int)RQ_RING(bo->rq)));
-
 
668
	assert(bo->refcnt);
-
 
669
	return bo->rq && RQ_RING(bo->rq) == I915_EXEC_RENDER;
-
 
670
}
-
 
671
 
-
 
672
static inline void kgem_bo_mark_unreusable(struct kgem_bo *bo)
-
 
673
{
-
 
674
	while (bo->proxy) {
605
}
675
		bo->flush = true;
-
 
676
		bo = bo->proxy;
-
 
677
	}
-
 
678
	bo->flush = true;
Line 606... Line 679...
606
 
679
	bo->reusable = false;
607
*/
680
}
608
 
681
 
609
static inline bool kgem_bo_is_dirty(struct kgem_bo *bo)
682
static inline bool kgem_bo_is_dirty(struct kgem_bo *bo)
Line 610... Line 683...
610
{
683
{
611
	if (bo == NULL)
684
	if (bo == NULL)
612
		return false;
685
		return false;
Line 613... Line 686...
613
 
686
 
614
	assert(bo->refcnt);
687
	assert(bo->refcnt);
615
	return bo->dirty;
688
	return bo->gpu_dirty;
Line 630... Line 703...
630
{
703
{
631
	DBG(("%s: handle=%d (proxy? %d)\n", __FUNCTION__,
704
	DBG(("%s: handle=%d (proxy? %d)\n", __FUNCTION__,
632
	     bo->handle, bo->proxy != NULL));
705
	     bo->handle, bo->proxy != NULL));
Line 633... Line 706...
633
 
706
 
634
	bo->exec->flags |= LOCAL_EXEC_OBJECT_WRITE;
707
	bo->exec->flags |= LOCAL_EXEC_OBJECT_WRITE;
635
	bo->needs_flush = bo->dirty = true;
708
	bo->needs_flush = bo->gpu_dirty = true;
636
	list_move(&bo->request, &RQ(bo->rq)->buffers);
709
	list_move(&bo->request, &RQ(bo->rq)->buffers);
Line 637... Line 710...
637
}
710
}
638
 
711
 
639
static inline void kgem_bo_mark_dirty(struct kgem_bo *bo)
712
static inline void kgem_bo_mark_dirty(struct kgem_bo *bo)
640
{
713
{
641
	assert(bo->refcnt);
714
	assert(bo->refcnt);
642
	do {
715
	do {
Line 643... Line 716...
643
		assert(bo->exec);
716
		assert(bo->exec);
644
		assert(bo->rq);
717
		assert(bo->rq);
Line 645... Line 718...
645
 
718
 
646
		if (bo->dirty)
719
		if (bo->gpu_dirty)
647
			return;
720
			return;
Line 670... Line 743...
670
#define MAX_INACTIVE_TIME 10
743
#define MAX_INACTIVE_TIME 10
671
bool kgem_expire_cache(struct kgem *kgem);
744
bool kgem_expire_cache(struct kgem *kgem);
672
void kgem_purge_cache(struct kgem *kgem);
745
void kgem_purge_cache(struct kgem *kgem);
673
void kgem_cleanup_cache(struct kgem *kgem);
746
void kgem_cleanup_cache(struct kgem *kgem);
Line -... Line 747...
-
 
747
 
-
 
748
void kgem_clean_scanout_cache(struct kgem *kgem);
-
 
749
void kgem_clean_large_cache(struct kgem *kgem);
674
 
750
 
675
#if HAS_DEBUG_FULL
751
#if HAS_DEBUG_FULL
676
void __kgem_batch_debug(struct kgem *kgem, uint32_t nbatch);
752
void __kgem_batch_debug(struct kgem *kgem, uint32_t nbatch);
677
#else
753
#else
678
static inline void __kgem_batch_debug(struct kgem *kgem, uint32_t nbatch)
754
static inline void __kgem_batch_debug(struct kgem *kgem, uint32_t nbatch)