kgem.h revision 13496ba1
103b705cfSriastradh/*
203b705cfSriastradh * Copyright (c) 2011 Intel Corporation
303b705cfSriastradh *
403b705cfSriastradh * Permission is hereby granted, free of charge, to any person obtaining a
503b705cfSriastradh * copy of this software and associated documentation files (the "Software"),
603b705cfSriastradh * to deal in the Software without restriction, including without limitation
703b705cfSriastradh * the rights to use, copy, modify, merge, publish, distribute, sublicense,
803b705cfSriastradh * and/or sell copies of the Software, and to permit persons to whom the
903b705cfSriastradh * Software is furnished to do so, subject to the following conditions:
1003b705cfSriastradh *
1103b705cfSriastradh * The above copyright notice and this permission notice (including the next
1203b705cfSriastradh * paragraph) shall be included in all copies or substantial portions of the
1303b705cfSriastradh * Software.
1403b705cfSriastradh *
1503b705cfSriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1603b705cfSriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1703b705cfSriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1803b705cfSriastradh * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1903b705cfSriastradh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2003b705cfSriastradh * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2103b705cfSriastradh * SOFTWARE.
2203b705cfSriastradh *
2303b705cfSriastradh * Authors:
2403b705cfSriastradh *    Chris Wilson <chris@chris-wilson.co.uk>
2503b705cfSriastradh *
2603b705cfSriastradh */
2703b705cfSriastradh
2803b705cfSriastradh#ifndef KGEM_H
2903b705cfSriastradh#define KGEM_H
3003b705cfSriastradh
3103b705cfSriastradh#include <stdint.h>
3203b705cfSriastradh#include <stdbool.h>
3303b705cfSriastradh#include <stdarg.h>
3403b705cfSriastradh
3503b705cfSriastradh#include <i915_drm.h>
3603b705cfSriastradh
3703b705cfSriastradh#include "compiler.h"
3813496ba1Ssnj#include "debug.h"
3903b705cfSriastradh
4003b705cfSriastradhstruct kgem_bo {
4103b705cfSriastradh	struct kgem_request *rq;
4203b705cfSriastradh#define RQ(rq) ((struct kgem_request *)((uintptr_t)(rq) & ~3))
4303b705cfSriastradh#define RQ_RING(rq) ((uintptr_t)(rq) & 3)
4403b705cfSriastradh#define RQ_IS_BLT(rq) (RQ_RING(rq) == KGEM_BLT)
4542542f5fSchristos#define MAKE_REQUEST(rq, ring) ((struct kgem_request *)((uintptr_t)(rq) | (ring)))
4642542f5fSchristos
4703b705cfSriastradh	struct drm_i915_gem_exec_object2 *exec;
4803b705cfSriastradh
4903b705cfSriastradh	struct kgem_bo *proxy;
5003b705cfSriastradh
5103b705cfSriastradh	struct list list;
5203b705cfSriastradh	struct list request;
5303b705cfSriastradh	struct list vma;
5403b705cfSriastradh
5542542f5fSchristos	void *map__cpu;
5642542f5fSchristos	void *map__gtt;
5713496ba1Ssnj	void *map__wc;
5803b705cfSriastradh#define MAP(ptr) ((void*)((uintptr_t)(ptr) & ~3))
5903b705cfSriastradh
6003b705cfSriastradh	struct kgem_bo_binding {
6103b705cfSriastradh		struct kgem_bo_binding *next;
6203b705cfSriastradh		uint32_t format;
6303b705cfSriastradh		uint16_t offset;
6403b705cfSriastradh	} binding;
6503b705cfSriastradh
6642542f5fSchristos	uint64_t presumed_offset;
6703b705cfSriastradh	uint32_t unique_id;
6803b705cfSriastradh	uint32_t refcnt;
6903b705cfSriastradh	uint32_t handle;
7003b705cfSriastradh	uint32_t target_handle;
7103b705cfSriastradh	uint32_t delta;
7242542f5fSchristos	uint32_t active_scanout;
7303b705cfSriastradh	union {
7403b705cfSriastradh		struct {
7503b705cfSriastradh			uint32_t count:27;
7603b705cfSriastradh#define PAGE_SIZE 4096
7703b705cfSriastradh			uint32_t bucket:5;
7803b705cfSriastradh#define NUM_CACHE_BUCKETS 16
7903b705cfSriastradh#define MAX_CACHE_SIZE (1 << (NUM_CACHE_BUCKETS+12))
8003b705cfSriastradh		} pages;
8103b705cfSriastradh		uint32_t bytes;
8203b705cfSriastradh	} size;
8303b705cfSriastradh	uint32_t pitch : 18; /* max 128k */
8403b705cfSriastradh	uint32_t tiling : 2;
8503b705cfSriastradh	uint32_t reusable : 1;
8603b705cfSriastradh	uint32_t gpu_dirty : 1;
8703b705cfSriastradh	uint32_t gtt_dirty : 1;
8803b705cfSriastradh	uint32_t domain : 2;
8903b705cfSriastradh	uint32_t needs_flush : 1;
9003b705cfSriastradh	uint32_t snoop : 1;
9103b705cfSriastradh	uint32_t io : 1;
9203b705cfSriastradh	uint32_t flush : 1;
9303b705cfSriastradh	uint32_t scanout : 1;
9442542f5fSchristos	uint32_t prime : 1;
9503b705cfSriastradh	uint32_t purged : 1;
9603b705cfSriastradh};
9703b705cfSriastradh#define DOMAIN_NONE 0
9803b705cfSriastradh#define DOMAIN_CPU 1
9903b705cfSriastradh#define DOMAIN_GTT 2
10003b705cfSriastradh#define DOMAIN_GPU 3
10103b705cfSriastradh
10203b705cfSriastradhstruct kgem_request {
10303b705cfSriastradh	struct list list;
10403b705cfSriastradh	struct kgem_bo *bo;
10503b705cfSriastradh	struct list buffers;
10603b705cfSriastradh	int ring;
10703b705cfSriastradh};
10803b705cfSriastradh
10903b705cfSriastradhenum {
11003b705cfSriastradh	MAP_GTT = 0,
11103b705cfSriastradh	MAP_CPU,
11203b705cfSriastradh	NUM_MAP_TYPES,
11303b705cfSriastradh};
11403b705cfSriastradh
11503b705cfSriastradhstruct kgem {
11642542f5fSchristos	unsigned wedged;
11713496ba1Ssnj	int fd;
11803b705cfSriastradh	unsigned gen;
11903b705cfSriastradh
12003b705cfSriastradh	uint32_t unique_id;
12103b705cfSriastradh
12213496ba1Ssnj	uint16_t nbatch;
12313496ba1Ssnj	uint16_t surface;
12413496ba1Ssnj	uint16_t nexec;
12513496ba1Ssnj	uint16_t nreloc;
12613496ba1Ssnj	uint16_t nreloc__self;
12713496ba1Ssnj	uint16_t nfence;
12813496ba1Ssnj	uint16_t batch_size;
12913496ba1Ssnj
13013496ba1Ssnj	uint32_t *batch;
13113496ba1Ssnj
13203b705cfSriastradh	enum kgem_mode {
13303b705cfSriastradh		/* order matches I915_EXEC_RING ordering */
13403b705cfSriastradh		KGEM_NONE = 0,
13503b705cfSriastradh		KGEM_RENDER,
13603b705cfSriastradh		KGEM_BSD,
13703b705cfSriastradh		KGEM_BLT,
13803b705cfSriastradh	} mode, ring;
13903b705cfSriastradh
14003b705cfSriastradh	struct list flushing;
14103b705cfSriastradh	struct list large;
14203b705cfSriastradh	struct list large_inactive;
14303b705cfSriastradh	struct list active[NUM_CACHE_BUCKETS][3];
14403b705cfSriastradh	struct list inactive[NUM_CACHE_BUCKETS];
14503b705cfSriastradh	struct list pinned_batches[2];
14603b705cfSriastradh	struct list snoop;
14703b705cfSriastradh	struct list scanout;
14803b705cfSriastradh	struct list batch_buffers, active_buffers;
14903b705cfSriastradh
15003b705cfSriastradh	struct list requests[2];
15113496ba1Ssnj	struct kgem_request *fence[2];
15203b705cfSriastradh	struct kgem_request *next_request;
15303b705cfSriastradh	struct kgem_request static_request;
15403b705cfSriastradh
15503b705cfSriastradh	struct {
15603b705cfSriastradh		struct list inactive[NUM_CACHE_BUCKETS];
15703b705cfSriastradh		int16_t count;
15803b705cfSriastradh	} vma[NUM_MAP_TYPES];
15903b705cfSriastradh
16003b705cfSriastradh	uint32_t batch_flags;
16103b705cfSriastradh	uint32_t batch_flags_base;
16203b705cfSriastradh#define I915_EXEC_SECURE (1<<9)
16303b705cfSriastradh#define LOCAL_EXEC_OBJECT_WRITE (1<<2)
16403b705cfSriastradh
16503b705cfSriastradh	uint32_t flush:1;
16603b705cfSriastradh	uint32_t need_expire:1;
16703b705cfSriastradh	uint32_t need_purge:1;
16803b705cfSriastradh	uint32_t need_retire:1;
16903b705cfSriastradh	uint32_t need_throttle:1;
17042542f5fSchristos	uint32_t needs_semaphore:1;
17142542f5fSchristos	uint32_t needs_reservation:1;
17203b705cfSriastradh	uint32_t scanout_busy:1;
17303b705cfSriastradh	uint32_t busy:1;
17403b705cfSriastradh
17503b705cfSriastradh	uint32_t has_create2 :1;
17603b705cfSriastradh	uint32_t has_userptr :1;
17703b705cfSriastradh	uint32_t has_blt :1;
17803b705cfSriastradh	uint32_t has_relaxed_fencing :1;
17903b705cfSriastradh	uint32_t has_relaxed_delta :1;
18003b705cfSriastradh	uint32_t has_semaphores :1;
18103b705cfSriastradh	uint32_t has_secure_batches :1;
18203b705cfSriastradh	uint32_t has_pinned_batches :1;
18303b705cfSriastradh	uint32_t has_caching :1;
18403b705cfSriastradh	uint32_t has_llc :1;
18503b705cfSriastradh	uint32_t has_wt :1;
18603b705cfSriastradh	uint32_t has_no_reloc :1;
18703b705cfSriastradh	uint32_t has_handle_lut :1;
18813496ba1Ssnj	uint32_t has_wc_mmap :1;
18903b705cfSriastradh
19003b705cfSriastradh	uint32_t can_blt_cpu :1;
19142542f5fSchristos	uint32_t can_render_y :1;
19203b705cfSriastradh
19303b705cfSriastradh	uint16_t fence_max;
19403b705cfSriastradh	uint16_t half_cpu_cache_pages;
19542542f5fSchristos	uint32_t aperture_total, aperture_high, aperture_low, aperture_mappable, aperture_fenceable;
19642542f5fSchristos	uint32_t aperture, aperture_fenced, aperture_max_fence;
19703b705cfSriastradh	uint32_t max_upload_tile_size, max_copy_tile_size;
19803b705cfSriastradh	uint32_t max_gpu_size, max_cpu_size;
19903b705cfSriastradh	uint32_t large_object_size, max_object_size;
20003b705cfSriastradh	uint32_t buffer_size;
20103b705cfSriastradh
20203b705cfSriastradh	void (*context_switch)(struct kgem *kgem, int new_mode);
20303b705cfSriastradh	void (*retire)(struct kgem *kgem);
20403b705cfSriastradh	void (*expire)(struct kgem *kgem);
20503b705cfSriastradh
20603b705cfSriastradh	void (*memcpy_to_tiled_x)(const void *src, void *dst, int bpp,
20703b705cfSriastradh				  int32_t src_stride, int32_t dst_stride,
20803b705cfSriastradh				  int16_t src_x, int16_t src_y,
20903b705cfSriastradh				  int16_t dst_x, int16_t dst_y,
21003b705cfSriastradh				  uint16_t width, uint16_t height);
21103b705cfSriastradh	void (*memcpy_from_tiled_x)(const void *src, void *dst, int bpp,
21203b705cfSriastradh				    int32_t src_stride, int32_t dst_stride,
21303b705cfSriastradh				    int16_t src_x, int16_t src_y,
21403b705cfSriastradh				    int16_t dst_x, int16_t dst_y,
21503b705cfSriastradh				    uint16_t width, uint16_t height);
21603b705cfSriastradh
21713496ba1Ssnj	struct kgem_bo *batch_bo;
21813496ba1Ssnj
21903b705cfSriastradh	uint16_t reloc__self[256];
22003b705cfSriastradh	struct drm_i915_gem_exec_object2 exec[384] page_aligned;
22103b705cfSriastradh	struct drm_i915_gem_relocation_entry reloc[8192] page_aligned;
22203b705cfSriastradh
22303b705cfSriastradh#ifdef DEBUG_MEMORY
22403b705cfSriastradh	struct {
22503b705cfSriastradh		int bo_allocs;
22603b705cfSriastradh		size_t bo_bytes;
22703b705cfSriastradh	} debug_memory;
22803b705cfSriastradh#endif
22903b705cfSriastradh};
23003b705cfSriastradh
23103b705cfSriastradh#define KGEM_MAX_DEFERRED_VBO 16
23203b705cfSriastradh
23303b705cfSriastradh#define KGEM_BATCH_RESERVED 1
23403b705cfSriastradh#define KGEM_RELOC_RESERVED (KGEM_MAX_DEFERRED_VBO)
23503b705cfSriastradh#define KGEM_EXEC_RESERVED (1+KGEM_MAX_DEFERRED_VBO)
23603b705cfSriastradh
23703b705cfSriastradh#ifndef ARRAY_SIZE
23803b705cfSriastradh#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
23903b705cfSriastradh#endif
24003b705cfSriastradh
24103b705cfSriastradh#define KGEM_BATCH_SIZE(K) ((K)->batch_size-KGEM_BATCH_RESERVED)
24203b705cfSriastradh#define KGEM_EXEC_SIZE(K) (int)(ARRAY_SIZE((K)->exec)-KGEM_EXEC_RESERVED)
24303b705cfSriastradh#define KGEM_RELOC_SIZE(K) (int)(ARRAY_SIZE((K)->reloc)-KGEM_RELOC_RESERVED)
24403b705cfSriastradh
24503b705cfSriastradhvoid kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen);
24603b705cfSriastradhvoid kgem_reset(struct kgem *kgem);
24703b705cfSriastradh
24803b705cfSriastradhstruct kgem_bo *kgem_create_map(struct kgem *kgem,
24903b705cfSriastradh				void *ptr, uint32_t size,
25003b705cfSriastradh				bool read_only);
25103b705cfSriastradh
25203b705cfSriastradhstruct kgem_bo *kgem_create_for_name(struct kgem *kgem, uint32_t name);
25303b705cfSriastradhstruct kgem_bo *kgem_create_for_prime(struct kgem *kgem, int name, uint32_t size);
25403b705cfSriastradhint kgem_bo_export_to_prime(struct kgem *kgem, struct kgem_bo *bo);
25503b705cfSriastradh
25603b705cfSriastradhstruct kgem_bo *kgem_create_linear(struct kgem *kgem, int size, unsigned flags);
25703b705cfSriastradhstruct kgem_bo *kgem_create_proxy(struct kgem *kgem,
25803b705cfSriastradh				  struct kgem_bo *target,
25903b705cfSriastradh				  int offset, int length);
26003b705cfSriastradh
26103b705cfSriastradhstruct kgem_bo *kgem_upload_source_image(struct kgem *kgem,
26203b705cfSriastradh					 const void *data,
26303b705cfSriastradh					 const BoxRec *box,
26403b705cfSriastradh					 int stride, int bpp);
26503b705cfSriastradhvoid kgem_proxy_bo_attach(struct kgem_bo *bo, struct kgem_bo **ptr);
26603b705cfSriastradh
26703b705cfSriastradhint kgem_choose_tiling(struct kgem *kgem,
26803b705cfSriastradh		       int tiling, int width, int height, int bpp);
26903b705cfSriastradhunsigned kgem_can_create_2d(struct kgem *kgem, int width, int height, int depth);
27003b705cfSriastradh#define KGEM_CAN_CREATE_GPU	0x1
27103b705cfSriastradh#define KGEM_CAN_CREATE_CPU	0x2
27203b705cfSriastradh#define KGEM_CAN_CREATE_LARGE	0x4
27303b705cfSriastradh#define KGEM_CAN_CREATE_GTT	0x8
27442542f5fSchristos#define KGEM_CAN_CREATE_TILED	0x10
27503b705cfSriastradh
27642542f5fSchristosbool kgem_check_surface_size(struct kgem *kgem,
27742542f5fSchristos			     uint32_t width,
27842542f5fSchristos			     uint32_t height,
27942542f5fSchristos			     uint32_t bpp,
28042542f5fSchristos			     uint32_t tiling,
28142542f5fSchristos			     uint32_t pitch,
28242542f5fSchristos			     uint32_t size);
28303b705cfSriastradh
28403b705cfSriastradhstruct kgem_bo *
28503b705cfSriastradhkgem_replace_bo(struct kgem *kgem,
28603b705cfSriastradh		struct kgem_bo *src,
28703b705cfSriastradh		uint32_t width,
28803b705cfSriastradh		uint32_t height,
28903b705cfSriastradh		uint32_t pitch,
29003b705cfSriastradh		uint32_t bpp);
29103b705cfSriastradhenum {
29203b705cfSriastradh	CREATE_EXACT = 0x1,
29303b705cfSriastradh	CREATE_INACTIVE = 0x2,
29403b705cfSriastradh	CREATE_CPU_MAP = 0x4,
29503b705cfSriastradh	CREATE_GTT_MAP = 0x8,
29603b705cfSriastradh	CREATE_SCANOUT = 0x10,
29703b705cfSriastradh	CREATE_PRIME = 0x20,
29803b705cfSriastradh	CREATE_TEMPORARY = 0x40,
29903b705cfSriastradh	CREATE_CACHED = 0x80,
30013496ba1Ssnj	CREATE_UNCACHED = 0x100,
30113496ba1Ssnj	CREATE_NO_RETIRE = 0x200,
30213496ba1Ssnj	CREATE_NO_THROTTLE = 0x400,
30303b705cfSriastradh};
30403b705cfSriastradhstruct kgem_bo *kgem_create_2d(struct kgem *kgem,
30503b705cfSriastradh			       int width,
30603b705cfSriastradh			       int height,
30703b705cfSriastradh			       int bpp,
30803b705cfSriastradh			       int tiling,
30903b705cfSriastradh			       uint32_t flags);
31003b705cfSriastradhstruct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem,
31103b705cfSriastradh				   int width,
31203b705cfSriastradh				   int height,
31303b705cfSriastradh				   int bpp,
31403b705cfSriastradh				   uint32_t flags);
31503b705cfSriastradh
31642542f5fSchristosbool kgem_bo_convert_to_gpu(struct kgem *kgem,
31742542f5fSchristos			    struct kgem_bo *bo,
31842542f5fSchristos			    unsigned flags);
31942542f5fSchristos
32003b705cfSriastradhuint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format);
32103b705cfSriastradhvoid kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset);
32203b705cfSriastradh
32303b705cfSriastradhbool kgem_retire(struct kgem *kgem);
32442542f5fSchristosvoid kgem_retire__buffers(struct kgem *kgem);
32542542f5fSchristos
32642542f5fSchristosstatic inline bool kgem_bo_discard_cache(struct kgem_bo *bo, bool force)
32742542f5fSchristos{
32842542f5fSchristos	if (bo == NULL || bo->proxy == NULL)
32942542f5fSchristos		return false;
33042542f5fSchristos
33142542f5fSchristos	if (force)
33242542f5fSchristos		return true;
33342542f5fSchristos
33442542f5fSchristos	if (bo->proxy->rq)
33542542f5fSchristos		return false;
33642542f5fSchristos
33742542f5fSchristos	return bo->snoop;
33842542f5fSchristos}
33903b705cfSriastradh
34003b705cfSriastradhbool __kgem_ring_is_idle(struct kgem *kgem, int ring);
34103b705cfSriastradhstatic inline bool kgem_ring_is_idle(struct kgem *kgem, int ring)
34203b705cfSriastradh{
34303b705cfSriastradh	ring = ring == KGEM_BLT;
34403b705cfSriastradh
34503b705cfSriastradh	if (list_is_empty(&kgem->requests[ring]))
34603b705cfSriastradh		return true;
34703b705cfSriastradh
34803b705cfSriastradh	return __kgem_ring_is_idle(kgem, ring);
34903b705cfSriastradh}
35003b705cfSriastradh
35103b705cfSriastradhstatic inline bool kgem_is_idle(struct kgem *kgem)
35203b705cfSriastradh{
35303b705cfSriastradh	if (!kgem->need_retire)
35403b705cfSriastradh		return true;
35503b705cfSriastradh
35603b705cfSriastradh	return kgem_ring_is_idle(kgem, kgem->ring);
35703b705cfSriastradh}
35803b705cfSriastradh
35903b705cfSriastradhstatic inline bool __kgem_ring_empty(struct kgem *kgem)
36003b705cfSriastradh{
36103b705cfSriastradh	return list_is_empty(&kgem->requests[kgem->ring == KGEM_BLT]);
36203b705cfSriastradh}
36303b705cfSriastradh
36403b705cfSriastradhvoid _kgem_submit(struct kgem *kgem);
36503b705cfSriastradhstatic inline void kgem_submit(struct kgem *kgem)
36603b705cfSriastradh{
36703b705cfSriastradh	if (kgem->nbatch)
36803b705cfSriastradh		_kgem_submit(kgem);
36903b705cfSriastradh}
37003b705cfSriastradh
37103b705cfSriastradhstatic inline void kgem_bo_submit(struct kgem *kgem, struct kgem_bo *bo)
37203b705cfSriastradh{
37342542f5fSchristos	if (bo->exec == NULL)
37442542f5fSchristos		return;
37542542f5fSchristos
37642542f5fSchristos	assert(bo->refcnt);
37742542f5fSchristos	_kgem_submit(kgem);
37803b705cfSriastradh}
37903b705cfSriastradh
38003b705cfSriastradhvoid kgem_scanout_flush(struct kgem *kgem, struct kgem_bo *bo);
38103b705cfSriastradh
38203b705cfSriastradhstatic inline struct kgem_bo *kgem_bo_reference(struct kgem_bo *bo)
38303b705cfSriastradh{
38403b705cfSriastradh	assert(bo->refcnt);
38503b705cfSriastradh	bo->refcnt++;
38603b705cfSriastradh	return bo;
38703b705cfSriastradh}
38803b705cfSriastradh
38903b705cfSriastradhvoid _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo);
39003b705cfSriastradhstatic inline void kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
39103b705cfSriastradh{
39203b705cfSriastradh	assert(bo->refcnt);
39303b705cfSriastradh	if (--bo->refcnt == 0)
39403b705cfSriastradh		_kgem_bo_destroy(kgem, bo);
39503b705cfSriastradh}
39603b705cfSriastradh
39703b705cfSriastradhvoid kgem_clear_dirty(struct kgem *kgem);
39803b705cfSriastradh
39903b705cfSriastradhstatic inline void kgem_set_mode(struct kgem *kgem,
40003b705cfSriastradh				 enum kgem_mode mode,
40103b705cfSriastradh				 struct kgem_bo *bo)
40203b705cfSriastradh{
40303b705cfSriastradh	assert(!kgem->wedged);
40403b705cfSriastradh
40503b705cfSriastradh#if DEBUG_FLUSH_BATCH
40603b705cfSriastradh	kgem_submit(kgem);
40703b705cfSriastradh#endif
40803b705cfSriastradh
40942542f5fSchristos	if (kgem->nreloc && bo->exec == NULL && kgem_ring_is_idle(kgem, kgem->ring)) {
41042542f5fSchristos		DBG(("%s: flushing before new bo\n", __FUNCTION__));
41103b705cfSriastradh		_kgem_submit(kgem);
41242542f5fSchristos	}
41303b705cfSriastradh
41403b705cfSriastradh	if (kgem->mode == mode)
41503b705cfSriastradh		return;
41603b705cfSriastradh
41703b705cfSriastradh	kgem->context_switch(kgem, mode);
41803b705cfSriastradh	kgem->mode = mode;
41903b705cfSriastradh}
42003b705cfSriastradh
42103b705cfSriastradhstatic inline void _kgem_set_mode(struct kgem *kgem, enum kgem_mode mode)
42203b705cfSriastradh{
42303b705cfSriastradh	assert(kgem->mode == KGEM_NONE);
42403b705cfSriastradh	assert(kgem->nbatch == 0);
42503b705cfSriastradh	assert(!kgem->wedged);
42603b705cfSriastradh	kgem->context_switch(kgem, mode);
42703b705cfSriastradh	kgem->mode = mode;
42803b705cfSriastradh}
42903b705cfSriastradh
43013496ba1Ssnjstatic inline int kgem_batch_space(struct kgem *kgem)
43113496ba1Ssnj{
43213496ba1Ssnj	int rem = kgem->surface - kgem->nbatch;
43313496ba1Ssnj	assert(rem > 0);
43413496ba1Ssnj	return rem - KGEM_BATCH_RESERVED;
43513496ba1Ssnj}
43613496ba1Ssnj
43703b705cfSriastradhstatic inline bool kgem_check_batch(struct kgem *kgem, int num_dwords)
43803b705cfSriastradh{
43903b705cfSriastradh	assert(num_dwords > 0);
44003b705cfSriastradh	assert(kgem->nbatch < kgem->surface);
44103b705cfSriastradh	assert(kgem->surface <= kgem->batch_size);
44203b705cfSriastradh	return likely(kgem->nbatch + num_dwords + KGEM_BATCH_RESERVED <= kgem->surface);
44303b705cfSriastradh}
44403b705cfSriastradh
44503b705cfSriastradhstatic inline bool kgem_check_reloc(struct kgem *kgem, int n)
44603b705cfSriastradh{
44703b705cfSriastradh	assert(kgem->nreloc <= KGEM_RELOC_SIZE(kgem));
44803b705cfSriastradh	return likely(kgem->nreloc + n <= KGEM_RELOC_SIZE(kgem));
44903b705cfSriastradh}
45003b705cfSriastradh
45103b705cfSriastradhstatic inline bool kgem_check_exec(struct kgem *kgem, int n)
45203b705cfSriastradh{
45303b705cfSriastradh	assert(kgem->nexec <= KGEM_EXEC_SIZE(kgem));
45403b705cfSriastradh	return likely(kgem->nexec + n <= KGEM_EXEC_SIZE(kgem));
45503b705cfSriastradh}
45603b705cfSriastradh
45703b705cfSriastradhstatic inline bool kgem_check_reloc_and_exec(struct kgem *kgem, int n)
45803b705cfSriastradh{
45903b705cfSriastradh	return kgem_check_reloc(kgem, n) && kgem_check_exec(kgem, n);
46003b705cfSriastradh}
46103b705cfSriastradh
46203b705cfSriastradhstatic inline bool kgem_check_batch_with_surfaces(struct kgem *kgem,
46303b705cfSriastradh						  int num_dwords,
46403b705cfSriastradh						  int num_surfaces)
46503b705cfSriastradh{
46603b705cfSriastradh	return (int)(kgem->nbatch + num_dwords + KGEM_BATCH_RESERVED) <= (int)(kgem->surface - num_surfaces*8) &&
46703b705cfSriastradh		kgem_check_reloc(kgem, num_surfaces) &&
46803b705cfSriastradh		kgem_check_exec(kgem, num_surfaces);
46903b705cfSriastradh}
47003b705cfSriastradh
47103b705cfSriastradhstatic inline uint32_t *kgem_get_batch(struct kgem *kgem)
47203b705cfSriastradh{
47303b705cfSriastradh	if (kgem->nreloc) {
47403b705cfSriastradh		unsigned mode = kgem->mode;
47503b705cfSriastradh		_kgem_submit(kgem);
47603b705cfSriastradh		_kgem_set_mode(kgem, mode);
47703b705cfSriastradh	}
47803b705cfSriastradh
47903b705cfSriastradh	return kgem->batch + kgem->nbatch;
48003b705cfSriastradh}
48103b705cfSriastradh
48203b705cfSriastradhbool kgem_check_bo(struct kgem *kgem, ...) __attribute__((sentinel(0)));
48303b705cfSriastradhbool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo);
48403b705cfSriastradhbool kgem_check_many_bo_fenced(struct kgem *kgem, ...) __attribute__((sentinel(0)));
48503b705cfSriastradh
48603b705cfSriastradh#define KGEM_RELOC_FENCED 0x8000
48703b705cfSriastradhuint32_t kgem_add_reloc(struct kgem *kgem,
48803b705cfSriastradh			uint32_t pos,
48903b705cfSriastradh			struct kgem_bo *bo,
49003b705cfSriastradh			uint32_t read_write_domains,
49103b705cfSriastradh			uint32_t delta);
49242542f5fSchristosuint64_t kgem_add_reloc64(struct kgem *kgem,
49342542f5fSchristos			  uint32_t pos,
49442542f5fSchristos			  struct kgem_bo *bo,
49542542f5fSchristos			  uint32_t read_write_domains,
49642542f5fSchristos			  uint64_t delta);
49703b705cfSriastradh
49803b705cfSriastradhvoid *kgem_bo_map(struct kgem *kgem, struct kgem_bo *bo);
49903b705cfSriastradhvoid *kgem_bo_map__async(struct kgem *kgem, struct kgem_bo *bo);
50003b705cfSriastradhvoid *kgem_bo_map__gtt(struct kgem *kgem, struct kgem_bo *bo);
50113496ba1Ssnjvoid *kgem_bo_map__wc(struct kgem *kgem, struct kgem_bo *bo);
50203b705cfSriastradhvoid kgem_bo_sync__gtt(struct kgem *kgem, struct kgem_bo *bo);
50303b705cfSriastradhvoid *kgem_bo_map__debug(struct kgem *kgem, struct kgem_bo *bo);
50403b705cfSriastradhvoid *kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo);
50503b705cfSriastradhvoid kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo *bo);
50603b705cfSriastradhvoid kgem_bo_sync__cpu_full(struct kgem *kgem, struct kgem_bo *bo, bool write);
50703b705cfSriastradhuint32_t kgem_bo_flink(struct kgem *kgem, struct kgem_bo *bo);
50803b705cfSriastradh
50903b705cfSriastradhbool kgem_bo_write(struct kgem *kgem, struct kgem_bo *bo,
51003b705cfSriastradh		   const void *data, int length);
51103b705cfSriastradh
51203b705cfSriastradhint kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo);
51342542f5fSchristosvoid kgem_get_tile_size(struct kgem *kgem, int tiling, int pitch,
51403b705cfSriastradh			int *tile_width, int *tile_height, int *tile_size);
51503b705cfSriastradh
51603b705cfSriastradhstatic inline int __kgem_buffer_size(struct kgem_bo *bo)
51703b705cfSriastradh{
51803b705cfSriastradh	assert(bo->proxy != NULL);
51903b705cfSriastradh	return bo->size.bytes;
52003b705cfSriastradh}
52103b705cfSriastradh
52203b705cfSriastradhstatic inline int __kgem_bo_size(struct kgem_bo *bo)
52303b705cfSriastradh{
52403b705cfSriastradh	assert(bo->proxy == NULL);
52503b705cfSriastradh	return PAGE_SIZE * bo->size.pages.count;
52603b705cfSriastradh}
52703b705cfSriastradh
52842542f5fSchristosstatic inline int __kgem_bo_num_pages(struct kgem_bo *bo)
52942542f5fSchristos{
53042542f5fSchristos	assert(bo->proxy == NULL);
53142542f5fSchristos	return bo->size.pages.count;
53242542f5fSchristos}
53342542f5fSchristos
53403b705cfSriastradhstatic inline int kgem_bo_size(struct kgem_bo *bo)
53503b705cfSriastradh{
53603b705cfSriastradh	if (bo->proxy)
53703b705cfSriastradh		return __kgem_buffer_size(bo);
53803b705cfSriastradh	else
53903b705cfSriastradh		return __kgem_bo_size(bo);
54003b705cfSriastradh}
54103b705cfSriastradh
54203b705cfSriastradhstatic inline bool kgem_bo_blt_pitch_is_ok(struct kgem *kgem,
54303b705cfSriastradh					   struct kgem_bo *bo)
54403b705cfSriastradh{
54503b705cfSriastradh	int pitch = bo->pitch;
54613496ba1Ssnj
54713496ba1Ssnj	if (kgem->gen >= 0100 && pitch & (1 << 4)) { /* bdw is broken */
54813496ba1Ssnj		DBG(("%s: can not blt to handle=%d, pitch=%d\n",
54913496ba1Ssnj		     __FUNCTION__, bo->handle, pitch));
55013496ba1Ssnj		return false;
55113496ba1Ssnj	}
55213496ba1Ssnj
55303b705cfSriastradh	if (kgem->gen >= 040 && bo->tiling)
55403b705cfSriastradh		pitch /= 4;
55503b705cfSriastradh	if (pitch > MAXSHORT) {
55603b705cfSriastradh		DBG(("%s: can not blt to handle=%d, adjusted pitch=%d\n",
55703b705cfSriastradh		     __FUNCTION__, bo->handle, pitch));
55803b705cfSriastradh		return false;
55903b705cfSriastradh	}
56003b705cfSriastradh
56103b705cfSriastradh	return true;
56203b705cfSriastradh}
56303b705cfSriastradh
56403b705cfSriastradhstatic inline bool kgem_bo_can_blt(struct kgem *kgem,
56503b705cfSriastradh				   struct kgem_bo *bo)
56603b705cfSriastradh{
56742542f5fSchristos	assert(bo->refcnt);
56842542f5fSchristos
56903b705cfSriastradh	if (bo->tiling == I915_TILING_Y) {
57003b705cfSriastradh		DBG(("%s: can not blt to handle=%d, tiling=Y\n",
57103b705cfSriastradh		     __FUNCTION__, bo->handle));
57203b705cfSriastradh		return false;
57303b705cfSriastradh	}
57403b705cfSriastradh
57513496ba1Ssnj	if (kgem->gen >= 0100 && bo->proxy && bo->delta & (1 << 4)) {
57613496ba1Ssnj		DBG(("%s: can not blt to handle=%d, delta=%d\n",
57713496ba1Ssnj		     __FUNCTION__, bo->handle, bo->delta));
57813496ba1Ssnj		return false;
57913496ba1Ssnj	}
58013496ba1Ssnj
58103b705cfSriastradh	return kgem_bo_blt_pitch_is_ok(kgem, bo);
58203b705cfSriastradh}
58303b705cfSriastradh
58403b705cfSriastradhstatic inline bool kgem_bo_is_snoop(struct kgem_bo *bo)
58503b705cfSriastradh{
58603b705cfSriastradh	assert(bo->refcnt);
58703b705cfSriastradh	while (bo->proxy)
58803b705cfSriastradh		bo = bo->proxy;
58903b705cfSriastradh	return bo->snoop;
59003b705cfSriastradh}
59103b705cfSriastradh
59203b705cfSriastradhvoid kgem_bo_undo(struct kgem *kgem, struct kgem_bo *bo);
59342542f5fSchristosvoid kgem_bo_pair_undo(struct kgem *kgem, struct kgem_bo *a, struct kgem_bo *b);
59403b705cfSriastradh
59503b705cfSriastradhbool __kgem_busy(struct kgem *kgem, int handle);
59603b705cfSriastradh
59742542f5fSchristosstatic inline void kgem_bo_mark_busy(struct kgem *kgem, struct kgem_bo *bo, int ring)
59803b705cfSriastradh{
59942542f5fSchristos	assert(bo->refcnt);
60042542f5fSchristos	bo->needs_flush = true;
60142542f5fSchristos	if (bo->rq) {
60242542f5fSchristos		bo->rq = MAKE_REQUEST(RQ(bo->rq), ring);
60342542f5fSchristos	} else {
60442542f5fSchristos		bo->rq = MAKE_REQUEST(kgem, ring);
60542542f5fSchristos		list_add(&bo->request, &kgem->flushing);
60642542f5fSchristos		kgem->need_retire = true;
60742542f5fSchristos	}
60803b705cfSriastradh}
60903b705cfSriastradh
61003b705cfSriastradhinline static void __kgem_bo_clear_busy(struct kgem_bo *bo)
61103b705cfSriastradh{
61242542f5fSchristos	DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
61303b705cfSriastradh	bo->rq = NULL;
61403b705cfSriastradh	list_del(&bo->request);
61503b705cfSriastradh
61603b705cfSriastradh	bo->domain = DOMAIN_NONE;
61703b705cfSriastradh	bo->needs_flush = false;
61803b705cfSriastradh	bo->gtt_dirty = false;
61903b705cfSriastradh}
62003b705cfSriastradh
62103b705cfSriastradhstatic inline bool kgem_bo_is_busy(struct kgem_bo *bo)
62203b705cfSriastradh{
62303b705cfSriastradh	DBG(("%s: handle=%d, domain: %d exec? %d, rq? %d\n", __FUNCTION__,
62403b705cfSriastradh	     bo->handle, bo->domain, bo->exec != NULL, bo->rq != NULL));
62503b705cfSriastradh	assert(bo->refcnt);
62603b705cfSriastradh	return bo->rq;
62703b705cfSriastradh}
62803b705cfSriastradh
62913496ba1Ssnjvoid __kgem_retire_requests_upto(struct kgem *kgem, struct kgem_bo *bo);
63003b705cfSriastradhstatic inline bool __kgem_bo_is_busy(struct kgem *kgem, struct kgem_bo *bo)
63103b705cfSriastradh{
63203b705cfSriastradh	DBG(("%s: handle=%d, domain: %d exec? %d, rq? %d\n", __FUNCTION__,
63303b705cfSriastradh	     bo->handle, bo->domain, bo->exec != NULL, bo->rq != NULL));
63403b705cfSriastradh	assert(bo->refcnt);
63503b705cfSriastradh
63603b705cfSriastradh	if (bo->exec)
63703b705cfSriastradh		return true;
63803b705cfSriastradh
63913496ba1Ssnj	if (bo->rq && !__kgem_busy(kgem, bo->handle)) {
64013496ba1Ssnj		__kgem_retire_requests_upto(kgem, bo);
64113496ba1Ssnj		assert(list_is_empty(&bo->request));
64213496ba1Ssnj		assert(bo->rq == NULL);
64313496ba1Ssnj		assert(bo->domain == DOMAIN_NONE);
64413496ba1Ssnj	}
64503b705cfSriastradh
64603b705cfSriastradh	return kgem_bo_is_busy(bo);
64703b705cfSriastradh}
64803b705cfSriastradh
64903b705cfSriastradhstatic inline bool kgem_bo_is_render(struct kgem_bo *bo)
65003b705cfSriastradh{
65103b705cfSriastradh	DBG(("%s: handle=%d, rq? %d [%d]\n", __FUNCTION__,
65242542f5fSchristos	     bo->handle, bo->rq != NULL, (int)RQ_RING(bo->rq)));
65303b705cfSriastradh	assert(bo->refcnt);
65403b705cfSriastradh	return bo->rq && RQ_RING(bo->rq) == I915_EXEC_RENDER;
65503b705cfSriastradh}
65603b705cfSriastradh
65703b705cfSriastradhstatic inline void kgem_bo_mark_unreusable(struct kgem_bo *bo)
65803b705cfSriastradh{
65942542f5fSchristos	assert(bo->refcnt);
66003b705cfSriastradh	while (bo->proxy) {
66103b705cfSriastradh		bo->flush = true;
66203b705cfSriastradh		bo = bo->proxy;
66342542f5fSchristos		assert(bo->refcnt);
66403b705cfSriastradh	}
66503b705cfSriastradh	bo->flush = true;
66603b705cfSriastradh	bo->reusable = false;
66703b705cfSriastradh}
66803b705cfSriastradh
66903b705cfSriastradhstatic inline bool kgem_bo_is_dirty(struct kgem_bo *bo)
67003b705cfSriastradh{
67103b705cfSriastradh	if (bo == NULL)
67203b705cfSriastradh		return false;
67303b705cfSriastradh
67403b705cfSriastradh	assert(bo->refcnt);
67503b705cfSriastradh	return bo->gpu_dirty;
67603b705cfSriastradh}
67703b705cfSriastradh
67803b705cfSriastradhstatic inline void kgem_bo_unclean(struct kgem *kgem, struct kgem_bo *bo)
67903b705cfSriastradh{
68003b705cfSriastradh	/* The bo is outside of our control, so presume it is written to */
68103b705cfSriastradh	bo->needs_flush = true;
68203b705cfSriastradh	if (bo->rq == NULL)
68303b705cfSriastradh		bo->rq = (void *)kgem;
68403b705cfSriastradh
68503b705cfSriastradh	if (bo->domain != DOMAIN_GPU)
68603b705cfSriastradh		bo->domain = DOMAIN_NONE;
68703b705cfSriastradh}
68803b705cfSriastradh
68903b705cfSriastradhstatic inline void __kgem_bo_mark_dirty(struct kgem_bo *bo)
69003b705cfSriastradh{
69103b705cfSriastradh	DBG(("%s: handle=%d (proxy? %d)\n", __FUNCTION__,
69203b705cfSriastradh	     bo->handle, bo->proxy != NULL));
69303b705cfSriastradh
69442542f5fSchristos	assert(bo->refcnt);
69542542f5fSchristos	assert(bo->exec);
69642542f5fSchristos	assert(bo->rq);
69742542f5fSchristos
69803b705cfSriastradh	bo->exec->flags |= LOCAL_EXEC_OBJECT_WRITE;
69903b705cfSriastradh	bo->needs_flush = bo->gpu_dirty = true;
70003b705cfSriastradh	list_move(&bo->request, &RQ(bo->rq)->buffers);
70103b705cfSriastradh}
70203b705cfSriastradh
70303b705cfSriastradhstatic inline void kgem_bo_mark_dirty(struct kgem_bo *bo)
70403b705cfSriastradh{
70503b705cfSriastradh	assert(bo->refcnt);
70603b705cfSriastradh	do {
70703b705cfSriastradh		assert(bo->exec);
70803b705cfSriastradh		assert(bo->rq);
70903b705cfSriastradh
71003b705cfSriastradh		if (bo->gpu_dirty)
71103b705cfSriastradh			return;
71203b705cfSriastradh
71303b705cfSriastradh		__kgem_bo_mark_dirty(bo);
71403b705cfSriastradh	} while ((bo = bo->proxy));
71503b705cfSriastradh}
71603b705cfSriastradh
71742542f5fSchristosstatic inline bool kgem_bo_mapped(struct kgem *kgem, struct kgem_bo *bo)
71842542f5fSchristos{
71942542f5fSchristos	DBG(("%s: handle=%d, map=%p:%p, tiling=%d, domain=%d\n",
72042542f5fSchristos	     __FUNCTION__, bo->handle, bo->map__gtt, bo->map__cpu, bo->tiling, bo->domain));
72142542f5fSchristos	assert(bo->proxy == NULL);
72242542f5fSchristos
72342542f5fSchristos	if (bo->tiling == I915_TILING_NONE && (bo->domain == DOMAIN_CPU || kgem->has_llc))
72442542f5fSchristos		return bo->map__cpu != NULL;
72542542f5fSchristos
72613496ba1Ssnj	if (bo->tiling == I915_TILING_NONE && bo->map__wc)
72713496ba1Ssnj		return true;
72813496ba1Ssnj
72942542f5fSchristos	return bo->map__gtt != NULL;
73042542f5fSchristos}
73142542f5fSchristos
73242542f5fSchristosstatic inline bool kgem_bo_can_map(struct kgem *kgem, struct kgem_bo *bo)
73342542f5fSchristos{
73413496ba1Ssnj	DBG(("%s: handle=%d, map=%p:%p:%p, tiling=%d, domain=%d, offset=%ld\n",
73513496ba1Ssnj	     __FUNCTION__, bo->handle, bo->map__gtt, bo->map__wc, bo->map__cpu, bo->tiling, bo->domain, (long)bo->presumed_offset));
73642542f5fSchristos
73742542f5fSchristos	if (!bo->tiling && (kgem->has_llc || bo->domain == DOMAIN_CPU))
73842542f5fSchristos		return true;
73942542f5fSchristos
74042542f5fSchristos	assert(bo->proxy == NULL);
74142542f5fSchristos
74242542f5fSchristos	if (bo->map__gtt != NULL)
74342542f5fSchristos		return true;
74442542f5fSchristos
74542542f5fSchristos	if (kgem->gen == 021 && bo->tiling == I915_TILING_Y)
74642542f5fSchristos		return false;
74742542f5fSchristos
74813496ba1Ssnj	if (!bo->tiling && kgem->has_wc_mmap)
74913496ba1Ssnj		return true;
75013496ba1Ssnj
75142542f5fSchristos	return __kgem_bo_num_pages(bo) <= kgem->aperture_mappable / 4;
75242542f5fSchristos}
75342542f5fSchristos
75442542f5fSchristosstatic inline bool kgem_bo_can_map__cpu(struct kgem *kgem,
75542542f5fSchristos					struct kgem_bo *bo,
75642542f5fSchristos					bool write)
75742542f5fSchristos{
75842542f5fSchristos	DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
75942542f5fSchristos	assert(bo->refcnt);
76042542f5fSchristos
76142542f5fSchristos	if (bo->purged || (bo->scanout && write)) {
76242542f5fSchristos		DBG(("%s: no, writing to scanout? %d, or is stolen [inaccessible via CPU]? %d\n",
76342542f5fSchristos		     __FUNCTION__, bo->scanout && write, bo->purged));
76442542f5fSchristos		return false;
76542542f5fSchristos	}
76642542f5fSchristos
76742542f5fSchristos	if (kgem->has_llc) {
76842542f5fSchristos		DBG(("%s: yes, has LLC and target is in LLC\n", __FUNCTION__));
76942542f5fSchristos		return true;
77042542f5fSchristos	}
77142542f5fSchristos
77242542f5fSchristos	DBG(("%s: non-LLC - CPU domain? %d, clean? %d\n",
77342542f5fSchristos	     __FUNCTION__, bo->domain == DOMAIN_CPU, !write || bo->exec == NULL));
77442542f5fSchristos	if (bo->domain != DOMAIN_CPU)
77542542f5fSchristos		return false;
77642542f5fSchristos
77742542f5fSchristos	return !write || bo->exec == NULL;
77842542f5fSchristos}
77942542f5fSchristos
78003b705cfSriastradh#define KGEM_BUFFER_WRITE	0x1
78103b705cfSriastradh#define KGEM_BUFFER_INPLACE	0x2
78203b705cfSriastradh#define KGEM_BUFFER_LAST	0x4
78303b705cfSriastradh
78403b705cfSriastradh#define KGEM_BUFFER_WRITE_INPLACE (KGEM_BUFFER_WRITE | KGEM_BUFFER_INPLACE)
78503b705cfSriastradh
78603b705cfSriastradhstruct kgem_bo *kgem_create_buffer(struct kgem *kgem,
78703b705cfSriastradh				   uint32_t size, uint32_t flags,
78803b705cfSriastradh				   void **ret);
78903b705cfSriastradhstruct kgem_bo *kgem_create_buffer_2d(struct kgem *kgem,
79003b705cfSriastradh				      int width, int height, int bpp,
79103b705cfSriastradh				      uint32_t flags,
79203b705cfSriastradh				      void **ret);
79303b705cfSriastradhbool kgem_buffer_is_inplace(struct kgem_bo *bo);
79403b705cfSriastradhvoid kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *bo);
79503b705cfSriastradh
79642542f5fSchristosint kgem_is_wedged(struct kgem *kgem);
79703b705cfSriastradhvoid kgem_throttle(struct kgem *kgem);
79803b705cfSriastradh#define MAX_INACTIVE_TIME 10
79903b705cfSriastradhbool kgem_expire_cache(struct kgem *kgem);
80042542f5fSchristosbool kgem_cleanup_cache(struct kgem *kgem);
80103b705cfSriastradh
80203b705cfSriastradhvoid kgem_clean_scanout_cache(struct kgem *kgem);
80303b705cfSriastradhvoid kgem_clean_large_cache(struct kgem *kgem);
80403b705cfSriastradh
80503b705cfSriastradh#if HAS_DEBUG_FULL
80603b705cfSriastradhvoid __kgem_batch_debug(struct kgem *kgem, uint32_t nbatch);
80703b705cfSriastradh#else
80803b705cfSriastradhstatic inline void __kgem_batch_debug(struct kgem *kgem, uint32_t nbatch)
80903b705cfSriastradh{
81003b705cfSriastradh	(void)kgem;
81103b705cfSriastradh	(void)nbatch;
81203b705cfSriastradh}
81303b705cfSriastradh#endif
81403b705cfSriastradh
81503b705cfSriastradhstatic inline void
81603b705cfSriastradhmemcpy_to_tiled_x(struct kgem *kgem,
81703b705cfSriastradh		  const void *src, void *dst, int bpp,
81803b705cfSriastradh		  int32_t src_stride, int32_t dst_stride,
81903b705cfSriastradh		  int16_t src_x, int16_t src_y,
82003b705cfSriastradh		  int16_t dst_x, int16_t dst_y,
82103b705cfSriastradh		  uint16_t width, uint16_t height)
82203b705cfSriastradh{
82342542f5fSchristos	assert(kgem->memcpy_to_tiled_x);
82442542f5fSchristos	assert(src_x >= 0 && src_y >= 0);
82542542f5fSchristos	assert(dst_x >= 0 && dst_y >= 0);
82642542f5fSchristos	assert(8*src_stride >= (src_x+width) * bpp);
82742542f5fSchristos	assert(8*dst_stride >= (dst_x+width) * bpp);
82803b705cfSriastradh	return kgem->memcpy_to_tiled_x(src, dst, bpp,
82903b705cfSriastradh				       src_stride, dst_stride,
83003b705cfSriastradh				       src_x, src_y,
83103b705cfSriastradh				       dst_x, dst_y,
83203b705cfSriastradh				       width, height);
83303b705cfSriastradh}
83403b705cfSriastradh
83503b705cfSriastradhstatic inline void
83603b705cfSriastradhmemcpy_from_tiled_x(struct kgem *kgem,
83703b705cfSriastradh		    const void *src, void *dst, int bpp,
83803b705cfSriastradh		    int32_t src_stride, int32_t dst_stride,
83903b705cfSriastradh		    int16_t src_x, int16_t src_y,
84003b705cfSriastradh		    int16_t dst_x, int16_t dst_y,
84103b705cfSriastradh		    uint16_t width, uint16_t height)
84203b705cfSriastradh{
84342542f5fSchristos	assert(kgem->memcpy_from_tiled_x);
84442542f5fSchristos	assert(src_x >= 0 && src_y >= 0);
84542542f5fSchristos	assert(dst_x >= 0 && dst_y >= 0);
84642542f5fSchristos	assert(8*src_stride >= (src_x+width) * bpp);
84742542f5fSchristos	assert(8*dst_stride >= (dst_x+width) * bpp);
84803b705cfSriastradh	return kgem->memcpy_from_tiled_x(src, dst, bpp,
84903b705cfSriastradh					 src_stride, dst_stride,
85003b705cfSriastradh					 src_x, src_y,
85103b705cfSriastradh					 dst_x, dst_y,
85203b705cfSriastradh					 width, height);
85303b705cfSriastradh}
85403b705cfSriastradh
85503b705cfSriastradhvoid choose_memcpy_tiled_x(struct kgem *kgem, int swizzling);
85603b705cfSriastradh
85703b705cfSriastradh#endif /* KGEM_H */
858