Subversion Repositories Kolibri OS

Rev

Rev 4251 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4251 Rev 4281
1
/*
1
/*
2
 * Copyright (c) 2011 Intel Corporation
2
 * Copyright (c) 2011 Intel Corporation
3
 *
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the "Software"),
5
 * copy of this software and associated documentation files (the "Software"),
6
 * to deal in the Software without restriction, including without limitation
6
 * to deal in the Software without restriction, including without limitation
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
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
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:
9
 * Software is furnished to do so, subject to the following conditions:
10
 *
10
 *
11
 * The above copyright notice and this permission notice (including the next
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
12
 * paragraph) shall be included in all copies or substantial portions of the
13
 * Software.
13
 * Software.
14
 *
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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,
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
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
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,
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
20
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
 * SOFTWARE.
21
 * SOFTWARE.
22
 *
22
 *
23
 * Authors:
23
 * Authors:
24
 *    Chris Wilson 
24
 *    Chris Wilson 
25
 *
25
 *
26
 */
26
 */
27
 
27
 
28
#ifdef HAVE_CONFIG_H
28
#ifdef HAVE_CONFIG_H
29
#include "config.h"
29
#include "config.h"
30
#endif
30
#endif
31
 
31
 
32
#include "sna.h"
32
#include "sna.h"
33
#include "sna_reg.h"
33
#include "sna_reg.h"
34
 
34
 
35
#include 
35
#include 
36
#include 
36
#include 
37
#include 
37
#include 
38
 
38
 
39
#ifdef HAVE_VALGRIND
39
#ifdef HAVE_VALGRIND
40
#include 
40
#include 
41
#include 
41
#include 
42
#endif
42
#endif
43
 
43
 
44
#ifdef HAVE_STRUCT_SYSINFO_TOTALRAM
44
#ifdef HAVE_STRUCT_SYSINFO_TOTALRAM
45
#include 
45
#include 
46
#endif
46
#endif
47
 
47
 
48
#include "sna_cpuid.h"
48
#include "sna_cpuid.h"
49
 
49
 
50
static struct kgem_bo *
50
static struct kgem_bo *
51
search_linear_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
51
search_linear_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
52
 
52
 
53
static struct kgem_bo *
53
static struct kgem_bo *
54
search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
54
search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
55
 
55
 
56
#define DBG_NO_HW 0
56
#define DBG_NO_HW 0
57
#define DBG_NO_TILING 0
57
#define DBG_NO_TILING 0
58
#define DBG_NO_CACHE 0
58
#define DBG_NO_CACHE 0
59
#define DBG_NO_CACHE_LEVEL 0
59
#define DBG_NO_CACHE_LEVEL 0
60
#define DBG_NO_CPU 0
60
#define DBG_NO_CPU 0
61
#define DBG_NO_CREATE2 1
61
#define DBG_NO_CREATE2 1
62
#define DBG_NO_USERPTR 0
62
#define DBG_NO_USERPTR 0
63
#define DBG_NO_UNSYNCHRONIZED_USERPTR 0
63
#define DBG_NO_UNSYNCHRONIZED_USERPTR 0
64
#define DBG_NO_LLC 0
64
#define DBG_NO_LLC 0
65
#define DBG_NO_SEMAPHORES 0
65
#define DBG_NO_SEMAPHORES 0
66
#define DBG_NO_MADV 1
66
#define DBG_NO_MADV 1
67
#define DBG_NO_UPLOAD_CACHE 0
67
#define DBG_NO_UPLOAD_CACHE 0
68
#define DBG_NO_UPLOAD_ACTIVE 0
68
#define DBG_NO_UPLOAD_ACTIVE 0
69
#define DBG_NO_MAP_UPLOAD 0
69
#define DBG_NO_MAP_UPLOAD 0
70
#define DBG_NO_RELAXED_FENCING 0
70
#define DBG_NO_RELAXED_FENCING 0
71
#define DBG_NO_SECURE_BATCHES 0
71
#define DBG_NO_SECURE_BATCHES 0
72
#define DBG_NO_PINNED_BATCHES 0
72
#define DBG_NO_PINNED_BATCHES 0
73
#define DBG_NO_FAST_RELOC 0
73
#define DBG_NO_FAST_RELOC 0
74
#define DBG_NO_HANDLE_LUT 1
74
#define DBG_NO_HANDLE_LUT 1
75
#define DBG_NO_WT 0
75
#define DBG_NO_WT 0
76
#define DBG_DUMP 0
76
#define DBG_DUMP 0
77
 
77
 
78
#define FORCE_MMAP_SYNC 0 /* ((1 << DOMAIN_CPU) | (1 << DOMAIN_GTT)) */
78
#define FORCE_MMAP_SYNC 0 /* ((1 << DOMAIN_CPU) | (1 << DOMAIN_GTT)) */
79
 
79
 
80
#ifndef DEBUG_SYNC
80
#ifndef DEBUG_SYNC
81
#define DEBUG_SYNC 0
81
#define DEBUG_SYNC 0
82
#endif
82
#endif
83
 
83
 
84
 
84
 
85
#if 0
85
#if 0
86
#define ASSERT_IDLE(kgem__, handle__) assert(!__kgem_busy(kgem__, handle__))
86
#define ASSERT_IDLE(kgem__, handle__) assert(!__kgem_busy(kgem__, handle__))
87
#define ASSERT_MAYBE_IDLE(kgem__, handle__, expect__) assert(!(expect__) || !__kgem_busy(kgem__, handle__))
87
#define ASSERT_MAYBE_IDLE(kgem__, handle__, expect__) assert(!(expect__) || !__kgem_busy(kgem__, handle__))
88
#else
88
#else
89
#define ASSERT_IDLE(kgem__, handle__)
89
#define ASSERT_IDLE(kgem__, handle__)
90
#define ASSERT_MAYBE_IDLE(kgem__, handle__, expect__)
90
#define ASSERT_MAYBE_IDLE(kgem__, handle__, expect__)
91
#endif
91
#endif
92
 
92
 
93
/* Worst case seems to be 965gm where we cannot write within a cacheline that
93
/* Worst case seems to be 965gm where we cannot write within a cacheline that
94
 * is being simultaneously being read by the GPU, or within the sampler
94
 * is being simultaneously being read by the GPU, or within the sampler
95
 * prefetch. In general, the chipsets seem to have a requirement that sampler
95
 * prefetch. In general, the chipsets seem to have a requirement that sampler
96
 * offsets be aligned to a cacheline (64 bytes).
96
 * offsets be aligned to a cacheline (64 bytes).
97
 */
97
 */
98
#define UPLOAD_ALIGNMENT 128
98
#define UPLOAD_ALIGNMENT 128
99
 
99
 
100
#define PAGE_ALIGN(x) ALIGN(x, PAGE_SIZE)
100
#define PAGE_ALIGN(x) ALIGN(x, PAGE_SIZE)
101
#define NUM_PAGES(x) (((x) + PAGE_SIZE-1) / PAGE_SIZE)
101
#define NUM_PAGES(x) (((x) + PAGE_SIZE-1) / PAGE_SIZE)
102
 
102
 
103
#define MAX_GTT_VMA_CACHE 512
103
#define MAX_GTT_VMA_CACHE 512
104
#define MAX_CPU_VMA_CACHE INT16_MAX
104
#define MAX_CPU_VMA_CACHE INT16_MAX
105
#define MAP_PRESERVE_TIME 10
105
#define MAP_PRESERVE_TIME 10
106
 
106
 
107
#define MAKE_CPU_MAP(ptr) ((void*)((uintptr_t)(ptr) | 1))
107
#define MAKE_CPU_MAP(ptr) ((void*)((uintptr_t)(ptr) | 1))
108
#define MAKE_USER_MAP(ptr) ((void*)((uintptr_t)(ptr) | 3))
108
#define MAKE_USER_MAP(ptr) ((void*)((uintptr_t)(ptr) | 3))
109
#define IS_USER_MAP(ptr) ((uintptr_t)(ptr) & 2)
109
#define IS_USER_MAP(ptr) ((uintptr_t)(ptr) & 2)
110
#define __MAP_TYPE(ptr) ((uintptr_t)(ptr) & 3)
110
#define __MAP_TYPE(ptr) ((uintptr_t)(ptr) & 3)
111
 
111
 
112
#define MAKE_REQUEST(rq, ring) ((struct kgem_request *)((uintptr_t)(rq) | (ring)))
112
#define MAKE_REQUEST(rq, ring) ((struct kgem_request *)((uintptr_t)(rq) | (ring)))
113
 
113
 
114
#define LOCAL_I915_PARAM_HAS_BLT		        11
114
#define LOCAL_I915_PARAM_HAS_BLT		        11
115
#define LOCAL_I915_PARAM_HAS_RELAXED_FENCING	12
115
#define LOCAL_I915_PARAM_HAS_RELAXED_FENCING	12
116
#define LOCAL_I915_PARAM_HAS_RELAXED_DELTA	    15
116
#define LOCAL_I915_PARAM_HAS_RELAXED_DELTA	    15
117
#define LOCAL_I915_PARAM_HAS_SEMAPHORES		    20
117
#define LOCAL_I915_PARAM_HAS_SEMAPHORES		    20
118
#define LOCAL_I915_PARAM_HAS_SECURE_BATCHES	    23
118
#define LOCAL_I915_PARAM_HAS_SECURE_BATCHES	    23
119
#define LOCAL_I915_PARAM_HAS_PINNED_BATCHES	    24
119
#define LOCAL_I915_PARAM_HAS_PINNED_BATCHES	    24
120
#define LOCAL_I915_PARAM_HAS_NO_RELOC		    25
120
#define LOCAL_I915_PARAM_HAS_NO_RELOC		    25
121
#define LOCAL_I915_PARAM_HAS_HANDLE_LUT		    26
121
#define LOCAL_I915_PARAM_HAS_HANDLE_LUT		    26
122
#define LOCAL_I915_PARAM_HAS_WT			27
122
#define LOCAL_I915_PARAM_HAS_WT			27
123
 
123
 
124
#define LOCAL_I915_EXEC_IS_PINNED		(1<<10)
124
#define LOCAL_I915_EXEC_IS_PINNED		(1<<10)
125
#define LOCAL_I915_EXEC_NO_RELOC		(1<<11)
125
#define LOCAL_I915_EXEC_NO_RELOC		(1<<11)
126
#define LOCAL_I915_EXEC_HANDLE_LUT		(1<<12)
126
#define LOCAL_I915_EXEC_HANDLE_LUT		(1<<12)
127
struct local_i915_gem_userptr {
127
struct local_i915_gem_userptr {
128
	uint64_t user_ptr;
128
	uint64_t user_ptr;
129
	uint64_t user_size;
129
	uint64_t user_size;
130
	uint32_t flags;
130
	uint32_t flags;
131
#define I915_USERPTR_READ_ONLY (1<<0)
131
#define I915_USERPTR_READ_ONLY (1<<0)
132
#define I915_USERPTR_UNSYNCHRONIZED (1<<31)
132
#define I915_USERPTR_UNSYNCHRONIZED (1<<31)
133
	uint32_t handle;
133
	uint32_t handle;
134
};
134
};
135
 
135
 
136
#define UNCACHED	0
136
#define UNCACHED	0
137
#define SNOOPED		1
137
#define SNOOPED		1
138
#define DISPLAY		2
138
#define DISPLAY		2
139
 
139
 
140
struct local_i915_gem_caching {
140
struct local_i915_gem_caching {
141
	uint32_t handle;
141
	uint32_t handle;
142
	uint32_t caching;
142
	uint32_t caching;
143
};
143
};
144
 
144
 
145
#define LOCAL_IOCTL_I915_GEM_SET_CACHING SRV_I915_GEM_SET_CACHING
145
#define LOCAL_IOCTL_I915_GEM_SET_CACHING SRV_I915_GEM_SET_CACHING
146
 
146
 
147
struct local_fbinfo {
147
struct local_fbinfo {
148
	int width;
148
	int width;
149
	int height;
149
	int height;
150
	int pitch;
150
	int pitch;
151
	int tiling;
151
	int tiling;
152
};
152
};
153
 
153
 
154
struct kgem_buffer {
154
struct kgem_buffer {
155
	struct kgem_bo base;
155
	struct kgem_bo base;
156
	void *mem;
156
	void *mem;
157
	uint32_t used;
157
	uint32_t used;
158
	uint32_t need_io : 1;
158
	uint32_t need_io : 1;
159
	uint32_t write : 2;
159
	uint32_t write : 2;
160
	uint32_t mmapped : 1;
160
	uint32_t mmapped : 1;
161
};
161
};
162
 
162
 
163
static struct kgem_bo *__kgem_freed_bo;
163
static struct kgem_bo *__kgem_freed_bo;
164
static struct kgem_request *__kgem_freed_request;
164
static struct kgem_request *__kgem_freed_request;
165
static struct drm_i915_gem_exec_object2 _kgem_dummy_exec;
165
static struct drm_i915_gem_exec_object2 _kgem_dummy_exec;
166
 
166
 
167
static inline int bytes(struct kgem_bo *bo)
167
static inline int bytes(struct kgem_bo *bo)
168
{
168
{
169
	return __kgem_bo_size(bo);
169
	return __kgem_bo_size(bo);
170
}
170
}
171
 
171
 
172
#define bucket(B) (B)->size.pages.bucket
172
#define bucket(B) (B)->size.pages.bucket
173
#define num_pages(B) (B)->size.pages.count
173
#define num_pages(B) (B)->size.pages.count
174
 
174
 
175
#ifdef DEBUG_MEMORY
175
#ifdef DEBUG_MEMORY
176
static void debug_alloc(struct kgem *kgem, size_t size)
176
static void debug_alloc(struct kgem *kgem, size_t size)
177
{
177
{
178
	kgem->debug_memory.bo_allocs++;
178
	kgem->debug_memory.bo_allocs++;
179
	kgem->debug_memory.bo_bytes += size;
179
	kgem->debug_memory.bo_bytes += size;
180
}
180
}
181
static void debug_alloc__bo(struct kgem *kgem, struct kgem_bo *bo)
181
static void debug_alloc__bo(struct kgem *kgem, struct kgem_bo *bo)
182
{
182
{
183
	debug_alloc(kgem, bytes(bo));
183
	debug_alloc(kgem, bytes(bo));
184
}
184
}
185
#else
185
#else
186
#define debug_alloc(k, b)
186
#define debug_alloc(k, b)
187
#define debug_alloc__bo(k, b)
187
#define debug_alloc__bo(k, b)
188
#endif
188
#endif
189
 
189
 
190
#ifndef NDEBUG
190
#ifndef NDEBUG
191
static void assert_tiling(struct kgem *kgem, struct kgem_bo *bo)
191
static void assert_tiling(struct kgem *kgem, struct kgem_bo *bo)
192
{
192
{
193
	struct drm_i915_gem_get_tiling tiling;
193
	struct drm_i915_gem_get_tiling tiling;
194
 
194
 
195
	assert(bo);
195
	assert(bo);
196
 
196
 
197
	VG_CLEAR(tiling);
197
	VG_CLEAR(tiling);
198
	tiling.handle = bo->handle;
198
	tiling.handle = bo->handle;
199
	tiling.tiling_mode = -1;
199
	tiling.tiling_mode = -1;
200
	(void)drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_TILING, &tiling);
200
	(void)drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_TILING, &tiling);
201
	assert(tiling.tiling_mode == bo->tiling);
201
	assert(tiling.tiling_mode == bo->tiling);
202
}
202
}
203
#else
203
#else
204
#define assert_tiling(kgem, bo)
204
#define assert_tiling(kgem, bo)
205
#endif
205
#endif
206
 
206
 
207
static void kgem_sna_reset(struct kgem *kgem)
207
static void kgem_sna_reset(struct kgem *kgem)
208
{
208
{
209
	struct sna *sna = container_of(kgem, struct sna, kgem);
209
	struct sna *sna = container_of(kgem, struct sna, kgem);
210
 
210
 
211
	sna->render.reset(sna);
211
	sna->render.reset(sna);
212
	sna->blt_state.fill_bo = 0;
212
	sna->blt_state.fill_bo = 0;
213
}
213
}
214
 
214
 
215
static void kgem_sna_flush(struct kgem *kgem)
215
static void kgem_sna_flush(struct kgem *kgem)
216
{
216
{
217
	struct sna *sna = container_of(kgem, struct sna, kgem);
217
	struct sna *sna = container_of(kgem, struct sna, kgem);
218
 
218
 
219
	sna->render.flush(sna);
219
	sna->render.flush(sna);
220
 
220
 
221
//	if (sna->render.solid_cache.dirty)
221
//	if (sna->render.solid_cache.dirty)
222
//		sna_render_flush_solid(sna);
222
//		sna_render_flush_solid(sna);
223
}
223
}
224
 
224
 
225
static bool gem_set_tiling(int fd, uint32_t handle, int tiling, int stride)
225
static bool gem_set_tiling(int fd, uint32_t handle, int tiling, int stride)
226
{
226
{
227
	struct drm_i915_gem_set_tiling set_tiling;
227
	struct drm_i915_gem_set_tiling set_tiling;
228
	int ret;
228
	int ret;
229
 
229
 
230
	if (DBG_NO_TILING)
230
	if (DBG_NO_TILING)
231
		return false;
231
		return false;
232
 
232
 
233
	VG_CLEAR(set_tiling);
233
	VG_CLEAR(set_tiling);
234
	do {
234
	do {
235
		set_tiling.handle = handle;
235
		set_tiling.handle = handle;
236
		set_tiling.tiling_mode = tiling;
236
		set_tiling.tiling_mode = tiling;
237
		set_tiling.stride = stride;
237
		set_tiling.stride = stride;
238
 
238
 
239
		ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling);
239
		ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling);
240
	} while (ret != 0);
240
	} while (ret != 0);
241
	return ret == 0;
241
	return ret == 0;
242
}
242
}
243
 
243
 
244
static bool gem_set_caching(int fd, uint32_t handle, int caching)
244
static bool gem_set_caching(int fd, uint32_t handle, int caching)
245
{
245
{
246
	struct local_i915_gem_caching arg;
246
	struct local_i915_gem_caching arg;
247
 
247
 
248
	VG_CLEAR(arg);
248
	VG_CLEAR(arg);
249
	arg.handle = handle;
249
	arg.handle = handle;
250
	arg.caching = caching;
250
	arg.caching = caching;
251
	return drmIoctl(fd, LOCAL_IOCTL_I915_GEM_SET_CACHING, &arg) == 0;
251
	return drmIoctl(fd, LOCAL_IOCTL_I915_GEM_SET_CACHING, &arg) == 0;
252
}
252
}
253
 
253
 
254
 
254
 
255
 
255
 
256
 
256
 
257
 
257
 
258
static bool __kgem_throttle_retire(struct kgem *kgem, unsigned flags)
258
static bool __kgem_throttle_retire(struct kgem *kgem, unsigned flags)
259
{
259
{
260
	if (flags & CREATE_NO_RETIRE) {
260
	if (flags & CREATE_NO_RETIRE) {
261
		DBG(("%s: not retiring per-request\n", __FUNCTION__));
261
		DBG(("%s: not retiring per-request\n", __FUNCTION__));
262
		return false;
262
		return false;
263
	}
263
	}
264
 
264
 
265
	if (!kgem->need_retire) {
265
	if (!kgem->need_retire) {
266
		DBG(("%s: nothing to retire\n", __FUNCTION__));
266
		DBG(("%s: nothing to retire\n", __FUNCTION__));
267
		return false;
267
		return false;
268
	}
268
	}
269
 
269
 
270
	if (kgem_retire(kgem))
270
	if (kgem_retire(kgem))
271
		return true;
271
		return true;
272
 
272
 
273
	if (flags & CREATE_NO_THROTTLE || !kgem->need_throttle) {
273
	if (flags & CREATE_NO_THROTTLE || !kgem->need_throttle) {
274
		DBG(("%s: not throttling\n", __FUNCTION__));
274
		DBG(("%s: not throttling\n", __FUNCTION__));
275
		return false;
275
		return false;
276
	}
276
	}
277
 
277
 
278
	kgem_throttle(kgem);
278
	kgem_throttle(kgem);
279
	return kgem_retire(kgem);
279
	return kgem_retire(kgem);
280
}
280
}
281
 
281
 
282
static void *__kgem_bo_map__gtt(struct kgem *kgem, struct kgem_bo *bo)
282
static void *__kgem_bo_map__gtt(struct kgem *kgem, struct kgem_bo *bo)
283
{
283
{
284
	struct drm_i915_gem_mmap_gtt mmap_arg;
284
	struct drm_i915_gem_mmap_gtt mmap_arg;
285
	void *ptr;
285
	void *ptr;
286
 
286
 
287
	DBG(("%s(handle=%d, size=%d)\n", __FUNCTION__,
287
	DBG(("%s(handle=%d, size=%d)\n", __FUNCTION__,
288
	     bo->handle, bytes(bo)));
288
	     bo->handle, bytes(bo)));
289
	assert(bo->proxy == NULL);
289
	assert(bo->proxy == NULL);
290
	assert(!bo->snoop);
290
	assert(!bo->snoop);
291
	assert(kgem_bo_can_map(kgem, bo));
291
	assert(kgem_bo_can_map(kgem, bo));
292
 
292
 
293
retry_gtt:
293
retry_gtt:
294
	VG_CLEAR(mmap_arg);
294
	VG_CLEAR(mmap_arg);
295
	mmap_arg.handle = bo->handle;
295
	mmap_arg.handle = bo->handle;
296
	if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &mmap_arg)) {
296
	if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &mmap_arg)) {
297
 
297
 
298
		(void)__kgem_throttle_retire(kgem, 0);
298
		(void)__kgem_throttle_retire(kgem, 0);
299
		if (kgem_expire_cache(kgem))
299
		if (kgem_expire_cache(kgem))
300
			goto retry_gtt;
300
			goto retry_gtt;
301
 
301
 
302
		if (kgem->need_expire) {
302
		if (kgem->need_expire) {
303
			kgem_cleanup_cache(kgem);
303
			kgem_cleanup_cache(kgem);
304
			goto retry_gtt;
304
			goto retry_gtt;
305
		}
305
		}
306
 
306
 
307
		printf("%s: failed to retrieve GTT offset for handle=%d\n",
307
		printf("%s: failed to retrieve GTT offset for handle=%d\n",
308
		       __FUNCTION__, bo->handle);
308
		       __FUNCTION__, bo->handle);
309
		return NULL;
309
		return NULL;
310
	}
310
	}
311
 
311
 
312
retry_mmap:
312
retry_mmap:
313
	ptr = (void*)(int)mmap_arg.offset;
313
	ptr = (void*)(int)mmap_arg.offset;
314
	if (ptr == NULL) {
314
	if (ptr == NULL) {
315
		ErrorF("%s: failed to mmap handle=%d, %d bytes, into GTT domain\n",
315
		ErrorF("%s: failed to mmap handle=%d, %d bytes, into GTT domain\n",
316
		       __FUNCTION__, bo->handle, bytes(bo));
316
		       __FUNCTION__, bo->handle, bytes(bo));
317
		ptr = NULL;
317
		ptr = NULL;
318
	}
318
	}
319
 
319
 
320
	return ptr;
320
	return ptr;
321
}
321
}
322
 
322
 
323
static int __gem_write(int fd, uint32_t handle,
323
static int __gem_write(int fd, uint32_t handle,
324
		       int offset, int length,
324
		       int offset, int length,
325
		       const void *src)
325
		       const void *src)
326
{
326
{
327
	struct drm_i915_gem_pwrite pwrite;
327
	struct drm_i915_gem_pwrite pwrite;
328
 
328
 
329
	DBG(("%s(handle=%d, offset=%d, len=%d)\n", __FUNCTION__,
329
	DBG(("%s(handle=%d, offset=%d, len=%d)\n", __FUNCTION__,
330
	     handle, offset, length));
330
	     handle, offset, length));
331
 
331
 
332
	VG_CLEAR(pwrite);
332
	VG_CLEAR(pwrite);
333
	pwrite.handle = handle;
333
	pwrite.handle = handle;
334
	pwrite.offset = offset;
334
	pwrite.offset = offset;
335
	pwrite.size = length;
335
	pwrite.size = length;
336
	pwrite.data_ptr = (uintptr_t)src;
336
	pwrite.data_ptr = (uintptr_t)src;
337
	return drmIoctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite);
337
	return drmIoctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite);
338
}
338
}
339
 
339
 
340
static int gem_write(int fd, uint32_t handle,
340
static int gem_write(int fd, uint32_t handle,
341
		     int offset, int length,
341
		     int offset, int length,
342
		     const void *src)
342
		     const void *src)
343
{
343
{
344
	struct drm_i915_gem_pwrite pwrite;
344
	struct drm_i915_gem_pwrite pwrite;
345
 
345
 
346
	DBG(("%s(handle=%d, offset=%d, len=%d)\n", __FUNCTION__,
346
	DBG(("%s(handle=%d, offset=%d, len=%d)\n", __FUNCTION__,
347
	     handle, offset, length));
347
	     handle, offset, length));
348
 
348
 
349
	VG_CLEAR(pwrite);
349
	VG_CLEAR(pwrite);
350
	pwrite.handle = handle;
350
	pwrite.handle = handle;
351
	/* align the transfer to cachelines; fortuitously this is safe! */
351
	/* align the transfer to cachelines; fortuitously this is safe! */
352
	if ((offset | length) & 63) {
352
	if ((offset | length) & 63) {
353
		pwrite.offset = offset & ~63;
353
		pwrite.offset = offset & ~63;
354
		pwrite.size = ALIGN(offset+length, 64) - pwrite.offset;
354
		pwrite.size = ALIGN(offset+length, 64) - pwrite.offset;
355
		pwrite.data_ptr = (uintptr_t)src + pwrite.offset - offset;
355
		pwrite.data_ptr = (uintptr_t)src + pwrite.offset - offset;
356
	} else {
356
	} else {
357
		pwrite.offset = offset;
357
		pwrite.offset = offset;
358
		pwrite.size = length;
358
		pwrite.size = length;
359
		pwrite.data_ptr = (uintptr_t)src;
359
		pwrite.data_ptr = (uintptr_t)src;
360
	}
360
	}
361
	return drmIoctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite);
361
	return drmIoctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite);
362
}
362
}
363
 
363
 
364
 
364
 
365
bool __kgem_busy(struct kgem *kgem, int handle)
365
bool __kgem_busy(struct kgem *kgem, int handle)
366
{
366
{
367
	struct drm_i915_gem_busy busy;
367
	struct drm_i915_gem_busy busy;
368
 
368
 
369
	VG_CLEAR(busy);
369
	VG_CLEAR(busy);
370
	busy.handle = handle;
370
	busy.handle = handle;
371
	busy.busy = !kgem->wedged;
371
	busy.busy = !kgem->wedged;
372
	(void)drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
372
	(void)drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
373
	DBG(("%s: handle=%d, busy=%d, wedged=%d\n",
373
	DBG(("%s: handle=%d, busy=%d, wedged=%d\n",
374
	     __FUNCTION__, handle, busy.busy, kgem->wedged));
374
	     __FUNCTION__, handle, busy.busy, kgem->wedged));
375
 
375
 
376
	return busy.busy;
376
	return busy.busy;
377
}
377
}
378
 
378
 
379
static void kgem_bo_retire(struct kgem *kgem, struct kgem_bo *bo)
379
static void kgem_bo_retire(struct kgem *kgem, struct kgem_bo *bo)
380
{
380
{
381
	DBG(("%s: retiring bo handle=%d (needed flush? %d), rq? %d [busy?=%d]\n",
381
	DBG(("%s: retiring bo handle=%d (needed flush? %d), rq? %d [busy?=%d]\n",
382
	     __FUNCTION__, bo->handle, bo->needs_flush, bo->rq != NULL,
382
	     __FUNCTION__, bo->handle, bo->needs_flush, bo->rq != NULL,
383
	     __kgem_busy(kgem, bo->handle)));
383
	     __kgem_busy(kgem, bo->handle)));
384
	assert(bo->exec == NULL);
384
	assert(bo->exec == NULL);
385
	assert(list_is_empty(&bo->vma));
385
	assert(list_is_empty(&bo->vma));
386
 
386
 
387
	if (bo->rq) {
387
	if (bo->rq) {
388
		if (!__kgem_busy(kgem, bo->handle)) {
388
		if (!__kgem_busy(kgem, bo->handle)) {
389
			__kgem_bo_clear_busy(bo);
389
			__kgem_bo_clear_busy(bo);
390
			kgem_retire(kgem);
390
			kgem_retire(kgem);
391
		}
391
		}
392
	} else {
392
	} else {
393
		assert(!bo->needs_flush);
393
		assert(!bo->needs_flush);
394
		ASSERT_IDLE(kgem, bo->handle);
394
		ASSERT_IDLE(kgem, bo->handle);
395
	}
395
	}
396
}
396
}
397
 
397
 
398
bool kgem_bo_write(struct kgem *kgem, struct kgem_bo *bo,
398
bool kgem_bo_write(struct kgem *kgem, struct kgem_bo *bo,
399
		   const void *data, int length)
399
		   const void *data, int length)
400
{
400
{
401
	assert(bo->refcnt);
401
	assert(bo->refcnt);
402
	assert(!bo->purged);
402
	assert(!bo->purged);
403
	assert(bo->proxy == NULL);
403
	assert(bo->proxy == NULL);
404
	ASSERT_IDLE(kgem, bo->handle);
404
	ASSERT_IDLE(kgem, bo->handle);
405
 
405
 
406
	assert(length <= bytes(bo));
406
	assert(length <= bytes(bo));
407
	if (gem_write(kgem->fd, bo->handle, 0, length, data))
407
	if (gem_write(kgem->fd, bo->handle, 0, length, data))
408
		return false;
408
		return false;
409
 
409
 
410
	DBG(("%s: flush=%d, domain=%d\n", __FUNCTION__, bo->flush, bo->domain));
410
	DBG(("%s: flush=%d, domain=%d\n", __FUNCTION__, bo->flush, bo->domain));
411
	if (bo->exec == NULL) {
411
	if (bo->exec == NULL) {
412
		kgem_bo_retire(kgem, bo);
412
		kgem_bo_retire(kgem, bo);
413
		bo->domain = DOMAIN_NONE;
413
		bo->domain = DOMAIN_NONE;
414
	}
414
	}
415
	bo->gtt_dirty = true;
415
	bo->gtt_dirty = true;
416
	return true;
416
	return true;
417
}
417
}
418
 
418
 
419
static uint32_t gem_create(int fd, int num_pages)
419
static uint32_t gem_create(int fd, int num_pages)
420
{
420
{
421
	struct drm_i915_gem_create create;
421
	struct drm_i915_gem_create create;
422
 
422
 
423
	VG_CLEAR(create);
423
	VG_CLEAR(create);
424
	create.handle = 0;
424
	create.handle = 0;
425
	create.size = PAGE_SIZE * num_pages;
425
	create.size = PAGE_SIZE * num_pages;
426
	(void)drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create);
426
	(void)drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create);
427
 
427
 
428
	return create.handle;
428
	return create.handle;
429
}
429
}
430
 
430
 
431
static bool
431
static bool
432
kgem_bo_set_purgeable(struct kgem *kgem, struct kgem_bo *bo)
432
kgem_bo_set_purgeable(struct kgem *kgem, struct kgem_bo *bo)
433
{
433
{
434
#if DBG_NO_MADV
434
#if DBG_NO_MADV
435
	return true;
435
	return true;
436
#else
436
#else
437
	struct drm_i915_gem_madvise madv;
437
	struct drm_i915_gem_madvise madv;
438
 
438
 
439
	assert(bo->exec == NULL);
439
	assert(bo->exec == NULL);
440
	assert(!bo->purged);
440
	assert(!bo->purged);
441
 
441
 
442
	VG_CLEAR(madv);
442
	VG_CLEAR(madv);
443
	madv.handle = bo->handle;
443
	madv.handle = bo->handle;
444
	madv.madv = I915_MADV_DONTNEED;
444
	madv.madv = I915_MADV_DONTNEED;
445
	if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv) == 0) {
445
	if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv) == 0) {
446
		bo->purged = 1;
446
		bo->purged = 1;
447
		kgem->need_purge |= !madv.retained && bo->domain == DOMAIN_GPU;
447
		kgem->need_purge |= !madv.retained && bo->domain == DOMAIN_GPU;
448
		return madv.retained;
448
		return madv.retained;
449
	}
449
	}
450
 
450
 
451
	return true;
451
	return true;
452
#endif
452
#endif
453
}
453
}
454
 
454
 
455
static bool
455
static bool
456
kgem_bo_is_retained(struct kgem *kgem, struct kgem_bo *bo)
456
kgem_bo_is_retained(struct kgem *kgem, struct kgem_bo *bo)
457
{
457
{
458
#if DBG_NO_MADV
458
#if DBG_NO_MADV
459
	return true;
459
	return true;
460
#else
460
#else
461
	struct drm_i915_gem_madvise madv;
461
	struct drm_i915_gem_madvise madv;
462
 
462
 
463
	if (!bo->purged)
463
	if (!bo->purged)
464
		return true;
464
		return true;
465
 
465
 
466
	VG_CLEAR(madv);
466
	VG_CLEAR(madv);
467
	madv.handle = bo->handle;
467
	madv.handle = bo->handle;
468
	madv.madv = I915_MADV_DONTNEED;
468
	madv.madv = I915_MADV_DONTNEED;
469
	if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv) == 0)
469
	if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv) == 0)
470
		return madv.retained;
470
		return madv.retained;
471
 
471
 
472
	return false;
472
	return false;
473
#endif
473
#endif
474
}
474
}
475
 
475
 
476
static bool
476
static bool
477
kgem_bo_clear_purgeable(struct kgem *kgem, struct kgem_bo *bo)
477
kgem_bo_clear_purgeable(struct kgem *kgem, struct kgem_bo *bo)
478
{
478
{
479
#if DBG_NO_MADV
479
#if DBG_NO_MADV
480
	return true;
480
	return true;
481
#else
481
#else
482
	struct drm_i915_gem_madvise madv;
482
	struct drm_i915_gem_madvise madv;
483
 
483
 
484
	assert(bo->purged);
484
	assert(bo->purged);
485
 
485
 
486
	VG_CLEAR(madv);
486
	VG_CLEAR(madv);
487
	madv.handle = bo->handle;
487
	madv.handle = bo->handle;
488
	madv.madv = I915_MADV_WILLNEED;
488
	madv.madv = I915_MADV_WILLNEED;
489
	if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv) == 0) {
489
	if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv) == 0) {
490
		bo->purged = !madv.retained;
490
		bo->purged = !madv.retained;
491
		kgem->need_purge |= !madv.retained && bo->domain == DOMAIN_GPU;
491
		kgem->need_purge |= !madv.retained && bo->domain == DOMAIN_GPU;
492
		return madv.retained;
492
		return madv.retained;
493
	}
493
	}
494
 
494
 
495
	return false;
495
	return false;
496
#endif
496
#endif
497
}
497
}
498
 
498
 
499
static void gem_close(int fd, uint32_t handle)
499
static void gem_close(int fd, uint32_t handle)
500
{
500
{
501
	struct drm_gem_close close;
501
	struct drm_gem_close close;
502
 
502
 
503
	VG_CLEAR(close);
503
	VG_CLEAR(close);
504
	close.handle = handle;
504
	close.handle = handle;
505
	(void)drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &close);
505
	(void)drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &close);
506
}
506
}
507
 
507
 
508
constant inline static unsigned long __fls(unsigned long word)
508
constant inline static unsigned long __fls(unsigned long word)
509
{
509
{
510
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86__) || defined(__x86_64__))
510
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86__) || defined(__x86_64__))
511
	asm("bsr %1,%0"
511
	asm("bsr %1,%0"
512
	    : "=r" (word)
512
	    : "=r" (word)
513
	    : "rm" (word));
513
	    : "rm" (word));
514
	return word;
514
	return word;
515
#else
515
#else
516
	unsigned int v = 0;
516
	unsigned int v = 0;
517
 
517
 
518
	while (word >>= 1)
518
	while (word >>= 1)
519
		v++;
519
		v++;
520
 
520
 
521
	return v;
521
	return v;
522
#endif
522
#endif
523
}
523
}
524
 
524
 
525
constant inline static int cache_bucket(int num_pages)
525
constant inline static int cache_bucket(int num_pages)
526
{
526
{
527
	return __fls(num_pages);
527
	return __fls(num_pages);
528
}
528
}
529
 
529
 
530
static struct kgem_bo *__kgem_bo_init(struct kgem_bo *bo,
530
static struct kgem_bo *__kgem_bo_init(struct kgem_bo *bo,
531
				      int handle, int num_pages)
531
				      int handle, int num_pages)
532
{
532
{
533
	assert(num_pages);
533
	assert(num_pages);
534
	memset(bo, 0, sizeof(*bo));
534
	memset(bo, 0, sizeof(*bo));
535
 
535
 
536
	bo->refcnt = 1;
536
	bo->refcnt = 1;
537
	bo->handle = handle;
537
	bo->handle = handle;
538
	bo->target_handle = -1;
538
	bo->target_handle = -1;
539
	num_pages(bo) = num_pages;
539
	num_pages(bo) = num_pages;
540
	bucket(bo) = cache_bucket(num_pages);
540
	bucket(bo) = cache_bucket(num_pages);
541
	bo->reusable = true;
541
	bo->reusable = true;
542
	bo->domain = DOMAIN_CPU;
542
	bo->domain = DOMAIN_CPU;
543
	list_init(&bo->request);
543
	list_init(&bo->request);
544
	list_init(&bo->list);
544
	list_init(&bo->list);
545
	list_init(&bo->vma);
545
	list_init(&bo->vma);
546
 
546
 
547
	return bo;
547
	return bo;
548
}
548
}
549
 
549
 
550
static struct kgem_bo *__kgem_bo_alloc(int handle, int num_pages)
550
static struct kgem_bo *__kgem_bo_alloc(int handle, int num_pages)
551
{
551
{
552
	struct kgem_bo *bo;
552
	struct kgem_bo *bo;
553
 
553
 
554
	if (__kgem_freed_bo) {
554
	if (__kgem_freed_bo) {
555
		bo = __kgem_freed_bo;
555
		bo = __kgem_freed_bo;
556
		__kgem_freed_bo = *(struct kgem_bo **)bo;
556
		__kgem_freed_bo = *(struct kgem_bo **)bo;
557
	} else {
557
	} else {
558
		bo = malloc(sizeof(*bo));
558
		bo = malloc(sizeof(*bo));
559
		if (bo == NULL)
559
		if (bo == NULL)
560
			return NULL;
560
			return NULL;
561
	}
561
	}
562
 
562
 
563
	return __kgem_bo_init(bo, handle, num_pages);
563
	return __kgem_bo_init(bo, handle, num_pages);
564
}
564
}
565
 
565
 
566
static struct kgem_request *__kgem_request_alloc(struct kgem *kgem)
566
static struct kgem_request *__kgem_request_alloc(struct kgem *kgem)
567
{
567
{
568
	struct kgem_request *rq;
568
	struct kgem_request *rq;
569
 
569
 
570
	rq = __kgem_freed_request;
570
	rq = __kgem_freed_request;
571
	if (rq) {
571
	if (rq) {
572
		__kgem_freed_request = *(struct kgem_request **)rq;
572
		__kgem_freed_request = *(struct kgem_request **)rq;
573
	} else {
573
	} else {
574
		rq = malloc(sizeof(*rq));
574
		rq = malloc(sizeof(*rq));
575
		if (rq == NULL)
575
		if (rq == NULL)
576
			rq = &kgem->static_request;
576
			rq = &kgem->static_request;
577
	}
577
	}
578
 
578
 
579
	list_init(&rq->buffers);
579
	list_init(&rq->buffers);
580
	rq->bo = NULL;
580
	rq->bo = NULL;
581
	rq->ring = 0;
581
	rq->ring = 0;
582
 
582
 
583
	return rq;
583
	return rq;
584
}
584
}
585
 
585
 
586
static void __kgem_request_free(struct kgem_request *rq)
586
static void __kgem_request_free(struct kgem_request *rq)
587
{
587
{
588
	_list_del(&rq->list);
588
	_list_del(&rq->list);
589
	*(struct kgem_request **)rq = __kgem_freed_request;
589
	*(struct kgem_request **)rq = __kgem_freed_request;
590
	__kgem_freed_request = rq;
590
	__kgem_freed_request = rq;
591
}
591
}
592
 
592
 
593
static struct list *inactive(struct kgem *kgem, int num_pages)
593
static struct list *inactive(struct kgem *kgem, int num_pages)
594
{
594
{
595
	assert(num_pages < MAX_CACHE_SIZE / PAGE_SIZE);
595
	assert(num_pages < MAX_CACHE_SIZE / PAGE_SIZE);
596
	assert(cache_bucket(num_pages) < NUM_CACHE_BUCKETS);
596
	assert(cache_bucket(num_pages) < NUM_CACHE_BUCKETS);
597
	return &kgem->inactive[cache_bucket(num_pages)];
597
	return &kgem->inactive[cache_bucket(num_pages)];
598
}
598
}
599
 
599
 
600
static struct list *active(struct kgem *kgem, int num_pages, int tiling)
600
static struct list *active(struct kgem *kgem, int num_pages, int tiling)
601
{
601
{
602
	assert(num_pages < MAX_CACHE_SIZE / PAGE_SIZE);
602
	assert(num_pages < MAX_CACHE_SIZE / PAGE_SIZE);
603
	assert(cache_bucket(num_pages) < NUM_CACHE_BUCKETS);
603
	assert(cache_bucket(num_pages) < NUM_CACHE_BUCKETS);
604
	return &kgem->active[cache_bucket(num_pages)][tiling];
604
	return &kgem->active[cache_bucket(num_pages)][tiling];
605
}
605
}
606
 
606
 
607
static size_t
607
static size_t
608
agp_aperture_size(struct pci_device *dev, unsigned gen)
608
agp_aperture_size(struct pci_device *dev, unsigned gen)
609
{
609
{
610
	/* XXX assume that only future chipsets are unknown and follow
610
	/* XXX assume that only future chipsets are unknown and follow
611
	 * the post gen2 PCI layout.
611
	 * the post gen2 PCI layout.
612
	 */
612
	 */
613
    return 0;
613
    return 0;
614
}
614
}
615
 
615
 
616
static size_t
616
static size_t
617
total_ram_size(void)
617
total_ram_size(void)
618
{
618
{
619
    uint32_t  data[9];
619
    uint32_t  data[9];
620
    size_t    size = 0;
620
    size_t    size = 0;
621
 
621
 
622
    asm volatile("int $0x40"
622
    asm volatile("int $0x40"
623
        : "=a" (size)
623
        : "=a" (size)
624
        : "a" (18),"b"(20), "c" (data)
624
        : "a" (18),"b"(20), "c" (data)
625
        : "memory");
625
        : "memory");
626
 
626
 
627
    return size != -1 ? size : 0;
627
    return size != -1 ? size : 0;
628
}
628
}
629
 
629
 
630
static unsigned
630
static unsigned
631
cpu_cache_size__cpuid4(void)
631
cpu_cache_size__cpuid4(void)
632
{
632
{
633
	/* Deterministic Cache Parmaeters (Function 04h)":
633
	/* Deterministic Cache Parmaeters (Function 04h)":
634
	 *    When EAX is initialized to a value of 4, the CPUID instruction
634
	 *    When EAX is initialized to a value of 4, the CPUID instruction
635
	 *    returns deterministic cache information in the EAX, EBX, ECX
635
	 *    returns deterministic cache information in the EAX, EBX, ECX
636
	 *    and EDX registers.  This function requires ECX be initialized
636
	 *    and EDX registers.  This function requires ECX be initialized
637
	 *    with an index which indicates which cache to return information
637
	 *    with an index which indicates which cache to return information
638
	 *    about. The OS is expected to call this function (CPUID.4) with
638
	 *    about. The OS is expected to call this function (CPUID.4) with
639
	 *    ECX = 0, 1, 2, until EAX[4:0] == 0, indicating no more caches.
639
	 *    ECX = 0, 1, 2, until EAX[4:0] == 0, indicating no more caches.
640
	 *    The order in which the caches are returned is not specified
640
	 *    The order in which the caches are returned is not specified
641
	 *    and may change at Intel's discretion.
641
	 *    and may change at Intel's discretion.
642
	 *
642
	 *
643
	 * Calculating the Cache Size in bytes:
643
	 * Calculating the Cache Size in bytes:
644
	 *          = (Ways +1) * (Partitions +1) * (Line Size +1) * (Sets +1)
644
	 *          = (Ways +1) * (Partitions +1) * (Line Size +1) * (Sets +1)
645
	 */
645
	 */
646
 
646
 
647
	 unsigned int eax, ebx, ecx, edx;
647
	 unsigned int eax, ebx, ecx, edx;
648
	 unsigned int llc_size = 0;
648
	 unsigned int llc_size = 0;
649
	 int cnt = 0;
649
	 int cnt = 0;
650
 
650
 
651
	 if (__get_cpuid_max(BASIC_CPUID, NULL) < 4)
651
	 if (__get_cpuid_max(BASIC_CPUID, NULL) < 4)
652
		 return 0;
652
		 return 0;
653
 
653
 
654
	 do {
654
	 do {
655
		 unsigned associativity, line_partitions, line_size, sets;
655
		 unsigned associativity, line_partitions, line_size, sets;
656
 
656
 
657
		 __cpuid_count(4, cnt++, eax, ebx, ecx, edx);
657
		 __cpuid_count(4, cnt++, eax, ebx, ecx, edx);
658
 
658
 
659
		 if ((eax & 0x1f) == 0)
659
		 if ((eax & 0x1f) == 0)
660
			 break;
660
			 break;
661
 
661
 
662
		 associativity = ((ebx >> 22) & 0x3ff) + 1;
662
		 associativity = ((ebx >> 22) & 0x3ff) + 1;
663
		 line_partitions = ((ebx >> 12) & 0x3ff) + 1;
663
		 line_partitions = ((ebx >> 12) & 0x3ff) + 1;
664
		 line_size = (ebx & 0xfff) + 1;
664
		 line_size = (ebx & 0xfff) + 1;
665
		 sets = ecx + 1;
665
		 sets = ecx + 1;
666
 
666
 
667
		 llc_size = associativity * line_partitions * line_size * sets;
667
		 llc_size = associativity * line_partitions * line_size * sets;
668
	 } while (1);
668
	 } while (1);
669
 
669
 
670
	 return llc_size;
670
	 return llc_size;
671
}
671
}
672
 
672
 
673
static int gem_param(struct kgem *kgem, int name)
673
static int gem_param(struct kgem *kgem, int name)
674
{
674
{
675
    drm_i915_getparam_t gp;
675
    drm_i915_getparam_t gp;
676
    int v = -1; /* No param uses the sign bit, reserve it for errors */
676
    int v = -1; /* No param uses the sign bit, reserve it for errors */
677
 
677
 
678
    VG_CLEAR(gp);
678
    VG_CLEAR(gp);
679
    gp.param = name;
679
    gp.param = name;
680
    gp.value = &v;
680
    gp.value = &v;
681
	if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GETPARAM, &gp))
681
	if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GETPARAM, &gp))
682
        return -1;
682
        return -1;
683
 
683
 
684
    VG(VALGRIND_MAKE_MEM_DEFINED(&v, sizeof(v)));
684
    VG(VALGRIND_MAKE_MEM_DEFINED(&v, sizeof(v)));
685
    return v;
685
    return v;
686
}
686
}
687
 
687
 
688
static bool test_has_execbuffer2(struct kgem *kgem)
688
static bool test_has_execbuffer2(struct kgem *kgem)
689
{
689
{
690
	return 1;
690
	return 1;
691
}
691
}
692
 
692
 
693
static bool test_has_no_reloc(struct kgem *kgem)
693
static bool test_has_no_reloc(struct kgem *kgem)
694
{
694
{
695
	if (DBG_NO_FAST_RELOC)
695
	if (DBG_NO_FAST_RELOC)
696
		return false;
696
		return false;
697
 
697
 
698
	return gem_param(kgem, LOCAL_I915_PARAM_HAS_NO_RELOC) > 0;
698
	return gem_param(kgem, LOCAL_I915_PARAM_HAS_NO_RELOC) > 0;
699
}
699
}
700
 
700
 
701
static bool test_has_handle_lut(struct kgem *kgem)
701
static bool test_has_handle_lut(struct kgem *kgem)
702
{
702
{
703
	if (DBG_NO_HANDLE_LUT)
703
	if (DBG_NO_HANDLE_LUT)
704
		return false;
704
		return false;
705
 
705
 
706
	return gem_param(kgem, LOCAL_I915_PARAM_HAS_HANDLE_LUT) > 0;
706
	return gem_param(kgem, LOCAL_I915_PARAM_HAS_HANDLE_LUT) > 0;
707
}
707
}
708
 
708
 
709
static bool test_has_wt(struct kgem *kgem)
709
static bool test_has_wt(struct kgem *kgem)
710
{
710
{
711
	if (DBG_NO_WT)
711
	if (DBG_NO_WT)
712
		return false;
712
		return false;
713
 
713
 
714
	return gem_param(kgem, LOCAL_I915_PARAM_HAS_WT) > 0;
714
	return gem_param(kgem, LOCAL_I915_PARAM_HAS_WT) > 0;
715
}
715
}
716
 
716
 
717
static bool test_has_semaphores_enabled(struct kgem *kgem)
717
static bool test_has_semaphores_enabled(struct kgem *kgem)
718
{
718
{
719
	bool detected = false;
719
	bool detected = false;
720
	int ret;
720
	int ret;
721
 
721
 
722
	if (DBG_NO_SEMAPHORES)
722
	if (DBG_NO_SEMAPHORES)
723
		return false;
723
		return false;
724
 
724
 
725
	ret = gem_param(kgem, LOCAL_I915_PARAM_HAS_SEMAPHORES);
725
	ret = gem_param(kgem, LOCAL_I915_PARAM_HAS_SEMAPHORES);
726
	if (ret != -1)
726
	if (ret != -1)
727
		return ret > 0;
727
		return ret > 0;
728
 
728
 
729
	return detected;
729
	return detected;
730
}
730
}
731
 
731
 
732
static bool __kgem_throttle(struct kgem *kgem)
732
static bool __kgem_throttle(struct kgem *kgem)
733
{
733
{
734
	if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_THROTTLE, NULL) == 0)
734
	if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_THROTTLE, NULL) == 0)
735
		return false;
735
		return false;
736
 
736
 
737
	return errno == EIO;
737
	return errno == EIO;
738
}
738
}
739
 
739
 
740
static bool is_hw_supported(struct kgem *kgem,
740
static bool is_hw_supported(struct kgem *kgem,
741
			    struct pci_device *dev)
741
			    struct pci_device *dev)
742
{
742
{
743
	if (DBG_NO_HW)
743
	if (DBG_NO_HW)
744
		return false;
744
		return false;
745
 
745
 
746
	if (!test_has_execbuffer2(kgem))
746
	if (!test_has_execbuffer2(kgem))
747
		return false;
747
		return false;
748
 
748
 
749
	if (kgem->gen == (unsigned)-1) /* unknown chipset, assume future gen */
749
	if (kgem->gen == (unsigned)-1) /* unknown chipset, assume future gen */
750
		return kgem->has_blt;
750
		return kgem->has_blt;
751
 
751
 
752
	/* Although pre-855gm the GMCH is fubar, it works mostly. So
752
	/* Although pre-855gm the GMCH is fubar, it works mostly. So
753
	 * let the user decide through "NoAccel" whether or not to risk
753
	 * let the user decide through "NoAccel" whether or not to risk
754
	 * hw acceleration.
754
	 * hw acceleration.
755
	 */
755
	 */
756
 
756
 
757
	if (kgem->gen == 060 && dev->revision < 8) {
757
	if (kgem->gen == 060 && dev->revision < 8) {
758
		/* pre-production SNB with dysfunctional BLT */
758
		/* pre-production SNB with dysfunctional BLT */
759
		return false;
759
		return false;
760
	}
760
	}
761
 
761
 
762
	if (kgem->gen >= 060) /* Only if the kernel supports the BLT ring */
762
	if (kgem->gen >= 060) /* Only if the kernel supports the BLT ring */
763
		return kgem->has_blt;
763
		return kgem->has_blt;
764
 
764
 
765
	return true;
765
	return true;
766
}
766
}
767
 
767
 
768
static bool test_has_relaxed_fencing(struct kgem *kgem)
768
static bool test_has_relaxed_fencing(struct kgem *kgem)
769
{
769
{
770
	if (kgem->gen < 040) {
770
	if (kgem->gen < 040) {
771
		if (DBG_NO_RELAXED_FENCING)
771
		if (DBG_NO_RELAXED_FENCING)
772
			return false;
772
			return false;
773
 
773
 
774
		return gem_param(kgem, LOCAL_I915_PARAM_HAS_RELAXED_FENCING) > 0;
774
		return gem_param(kgem, LOCAL_I915_PARAM_HAS_RELAXED_FENCING) > 0;
775
	} else
775
	} else
776
		return true;
776
		return true;
777
}
777
}
778
 
778
 
779
static bool test_has_llc(struct kgem *kgem)
779
static bool test_has_llc(struct kgem *kgem)
780
{
780
{
781
	int has_llc = -1;
781
	int has_llc = -1;
782
 
782
 
783
	if (DBG_NO_LLC)
783
	if (DBG_NO_LLC)
784
		return false;
784
		return false;
785
 
785
 
786
#if defined(I915_PARAM_HAS_LLC) /* Expected in libdrm-2.4.31 */
786
#if defined(I915_PARAM_HAS_LLC) /* Expected in libdrm-2.4.31 */
787
	has_llc = gem_param(kgem, I915_PARAM_HAS_LLC);
787
	has_llc = gem_param(kgem, I915_PARAM_HAS_LLC);
788
#endif
788
#endif
789
	if (has_llc == -1) {
789
	if (has_llc == -1) {
790
		DBG(("%s: no kernel/drm support for HAS_LLC, assuming support for LLC based on GPU generation\n", __FUNCTION__));
790
		DBG(("%s: no kernel/drm support for HAS_LLC, assuming support for LLC based on GPU generation\n", __FUNCTION__));
791
		has_llc = kgem->gen >= 060;
791
		has_llc = kgem->gen >= 060;
792
	}
792
	}
793
 
793
 
794
	return has_llc;
794
	return has_llc;
795
}
795
}
796
 
796
 
797
static bool test_has_caching(struct kgem *kgem)
797
static bool test_has_caching(struct kgem *kgem)
798
{
798
{
799
	uint32_t handle;
799
	uint32_t handle;
800
	bool ret;
800
	bool ret;
801
 
801
 
802
	if (DBG_NO_CACHE_LEVEL)
802
	if (DBG_NO_CACHE_LEVEL)
803
		return false;
803
		return false;
804
 
804
 
805
	/* Incoherent blt and sampler hangs the GPU */
805
	/* Incoherent blt and sampler hangs the GPU */
806
	if (kgem->gen == 040)
806
	if (kgem->gen == 040)
807
		return false;
807
		return false;
808
 
808
 
809
	handle = gem_create(kgem->fd, 1);
809
	handle = gem_create(kgem->fd, 1);
810
	if (handle == 0)
810
	if (handle == 0)
811
		return false;
811
		return false;
812
 
812
 
813
	ret = gem_set_caching(kgem->fd, handle, UNCACHED);
813
	ret = gem_set_caching(kgem->fd, handle, UNCACHED);
814
	gem_close(kgem->fd, handle);
814
	gem_close(kgem->fd, handle);
815
	return ret;
815
	return ret;
816
}
816
}
817
 
817
 
818
static bool test_has_userptr(struct kgem *kgem)
818
static bool test_has_userptr(struct kgem *kgem)
819
{
819
{
820
#if defined(USE_USERPTR)
820
#if defined(USE_USERPTR)
821
	uint32_t handle;
821
	uint32_t handle;
822
	void *ptr;
822
	void *ptr;
823
 
823
 
824
	if (DBG_NO_USERPTR)
824
	if (DBG_NO_USERPTR)
825
		return false;
825
		return false;
826
 
826
 
827
	/* Incoherent blt and sampler hangs the GPU */
827
	/* Incoherent blt and sampler hangs the GPU */
828
	if (kgem->gen == 040)
828
	if (kgem->gen == 040)
829
		return false;
829
		return false;
830
 
830
 
831
	if (posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE))
831
	if (posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE))
832
		return false;
832
		return false;
833
 
833
 
834
	handle = gem_userptr(kgem->fd, ptr, PAGE_SIZE, false);
834
	handle = gem_userptr(kgem->fd, ptr, PAGE_SIZE, false);
835
	gem_close(kgem->fd, handle);
835
	gem_close(kgem->fd, handle);
836
	free(ptr);
836
	free(ptr);
837
 
837
 
838
	return handle != 0;
838
	return handle != 0;
839
#else
839
#else
840
	return false;
840
	return false;
841
#endif
841
#endif
842
}
842
}
843
 
843
 
844
static bool test_has_create2(struct kgem *kgem)
844
static bool test_has_create2(struct kgem *kgem)
845
{
845
{
846
#if defined(USE_CREATE2)
846
#if defined(USE_CREATE2)
847
	struct local_i915_gem_create2 args;
847
	struct local_i915_gem_create2 args;
848
 
848
 
849
	if (DBG_NO_CREATE2)
849
	if (DBG_NO_CREATE2)
850
		return false;
850
		return false;
851
 
851
 
852
	memset(&args, 0, sizeof(args));
852
	memset(&args, 0, sizeof(args));
853
	args.size = PAGE_SIZE;
853
	args.size = PAGE_SIZE;
854
	args.caching = DISPLAY;
854
	args.caching = DISPLAY;
855
	if (drmIoctl(kgem->fd, LOCAL_IOCTL_I915_GEM_CREATE2, &args) == 0)
855
	if (drmIoctl(kgem->fd, LOCAL_IOCTL_I915_GEM_CREATE2, &args) == 0)
856
		gem_close(kgem->fd, args.handle);
856
		gem_close(kgem->fd, args.handle);
857
 
857
 
858
	return args.handle != 0;
858
	return args.handle != 0;
859
#else
859
#else
860
	return false;
860
	return false;
861
#endif
861
#endif
862
}
862
}
863
 
863
 
864
static bool test_has_secure_batches(struct kgem *kgem)
864
static bool test_has_secure_batches(struct kgem *kgem)
865
{
865
{
866
	if (DBG_NO_SECURE_BATCHES)
866
	if (DBG_NO_SECURE_BATCHES)
867
		return false;
867
		return false;
868
 
868
 
869
	return gem_param(kgem, LOCAL_I915_PARAM_HAS_SECURE_BATCHES) > 0;
869
	return gem_param(kgem, LOCAL_I915_PARAM_HAS_SECURE_BATCHES) > 0;
870
}
870
}
871
 
871
 
872
static bool test_has_pinned_batches(struct kgem *kgem)
872
static bool test_has_pinned_batches(struct kgem *kgem)
873
{
873
{
874
	if (DBG_NO_PINNED_BATCHES)
874
	if (DBG_NO_PINNED_BATCHES)
875
		return false;
875
		return false;
876
 
876
 
877
	return gem_param(kgem, LOCAL_I915_PARAM_HAS_PINNED_BATCHES) > 0;
877
	return gem_param(kgem, LOCAL_I915_PARAM_HAS_PINNED_BATCHES) > 0;
878
}
878
}
879
 
879
 
880
 
880
 
881
static bool kgem_init_pinned_batches(struct kgem *kgem)
881
static bool kgem_init_pinned_batches(struct kgem *kgem)
882
{
882
{
883
	int count[2] = { 2, 1 };
883
	int count[2] = { 2, 1 };
884
	int size[2] = { 1, 2 };
884
	int size[2] = { 1, 2 };
885
	int n, i;
885
	int n, i;
886
 
886
 
887
	if (kgem->wedged)
887
	if (kgem->wedged)
888
		return true;
888
		return true;
889
 
889
 
890
	for (n = 0; n < ARRAY_SIZE(count); n++) {
890
	for (n = 0; n < ARRAY_SIZE(count); n++) {
891
		for (i = 0; i < count[n]; i++) {
891
		for (i = 0; i < count[n]; i++) {
892
			struct drm_i915_gem_pin pin;
892
			struct drm_i915_gem_pin pin;
893
			struct kgem_bo *bo;
893
			struct kgem_bo *bo;
894
 
894
 
895
			VG_CLEAR(pin);
895
			VG_CLEAR(pin);
896
 
896
 
897
			pin.handle = gem_create(kgem->fd, size[n]);
897
			pin.handle = gem_create(kgem->fd, size[n]);
898
			if (pin.handle == 0)
898
			if (pin.handle == 0)
899
				goto err;
899
				goto err;
900
 
900
 
901
			DBG(("%s: new handle=%d, num_pages=%d\n",
901
			DBG(("%s: new handle=%d, num_pages=%d\n",
902
			     __FUNCTION__, pin.handle, size[n]));
902
			     __FUNCTION__, pin.handle, size[n]));
903
 
903
 
904
			bo = __kgem_bo_alloc(pin.handle, size[n]);
904
			bo = __kgem_bo_alloc(pin.handle, size[n]);
905
			if (bo == NULL) {
905
			if (bo == NULL) {
906
				gem_close(kgem->fd, pin.handle);
906
				gem_close(kgem->fd, pin.handle);
907
				goto err;
907
				goto err;
908
			}
908
			}
909
 
909
 
910
			pin.alignment = 0;
910
			pin.alignment = 0;
911
			if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_PIN, &pin)) {
911
			if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_PIN, &pin)) {
912
				gem_close(kgem->fd, pin.handle);
912
				gem_close(kgem->fd, pin.handle);
913
				goto err;
913
				goto err;
914
			}
914
			}
915
			bo->presumed_offset = pin.offset;
915
			bo->presumed_offset = pin.offset;
916
			debug_alloc__bo(kgem, bo);
916
			debug_alloc__bo(kgem, bo);
917
			list_add(&bo->list, &kgem->pinned_batches[n]);
917
			list_add(&bo->list, &kgem->pinned_batches[n]);
918
		}
918
		}
919
	}
919
	}
920
 
920
 
921
	return true;
921
	return true;
922
 
922
 
923
err:
923
err:
924
	for (n = 0; n < ARRAY_SIZE(kgem->pinned_batches); n++) {
924
	for (n = 0; n < ARRAY_SIZE(kgem->pinned_batches); n++) {
925
		while (!list_is_empty(&kgem->pinned_batches[n])) {
925
		while (!list_is_empty(&kgem->pinned_batches[n])) {
926
			kgem_bo_destroy(kgem,
926
			kgem_bo_destroy(kgem,
927
					list_first_entry(&kgem->pinned_batches[n],
927
					list_first_entry(&kgem->pinned_batches[n],
928
							 struct kgem_bo, list));
928
							 struct kgem_bo, list));
929
		}
929
		}
930
	}
930
	}
931
 
931
 
932
	/* For simplicity populate the lists with a single unpinned bo */
932
	/* For simplicity populate the lists with a single unpinned bo */
933
	for (n = 0; n < ARRAY_SIZE(count); n++) {
933
	for (n = 0; n < ARRAY_SIZE(count); n++) {
934
		struct kgem_bo *bo;
934
		struct kgem_bo *bo;
935
		uint32_t handle;
935
		uint32_t handle;
936
 
936
 
937
		handle = gem_create(kgem->fd, size[n]);
937
		handle = gem_create(kgem->fd, size[n]);
938
		if (handle == 0)
938
		if (handle == 0)
939
			break;
939
			break;
940
 
940
 
941
		bo = __kgem_bo_alloc(handle, size[n]);
941
		bo = __kgem_bo_alloc(handle, size[n]);
942
		if (bo == NULL) {
942
		if (bo == NULL) {
943
			gem_close(kgem->fd, handle);
943
			gem_close(kgem->fd, handle);
944
			break;
944
			break;
945
		}
945
		}
946
 
946
 
947
		debug_alloc__bo(kgem, bo);
947
		debug_alloc__bo(kgem, bo);
948
		list_add(&bo->list, &kgem->pinned_batches[n]);
948
		list_add(&bo->list, &kgem->pinned_batches[n]);
949
	}
949
	}
950
	return false;
950
	return false;
951
}
951
}
952
 
952
 
953
void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
953
void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
954
{
954
{
955
    struct drm_i915_gem_get_aperture aperture;
955
    struct drm_i915_gem_get_aperture aperture;
956
    size_t totalram;
956
    size_t totalram;
957
    unsigned half_gpu_max;
957
    unsigned half_gpu_max;
958
    unsigned int i, j;
958
    unsigned int i, j;
959
 
959
 
960
    DBG(("%s: fd=%d, gen=%d\n", __FUNCTION__, fd, gen));
960
    DBG(("%s: fd=%d, gen=%d\n", __FUNCTION__, fd, gen));
961
 
961
 
962
    memset(kgem, 0, sizeof(*kgem));
962
    memset(kgem, 0, sizeof(*kgem));
963
 
963
 
964
    kgem->fd = fd;
964
    kgem->fd = fd;
965
    kgem->gen = gen;
965
    kgem->gen = gen;
966
 
966
 
967
    list_init(&kgem->requests[0]);
967
    list_init(&kgem->requests[0]);
968
    list_init(&kgem->requests[1]);
968
    list_init(&kgem->requests[1]);
969
    list_init(&kgem->batch_buffers);
969
    list_init(&kgem->batch_buffers);
970
    list_init(&kgem->active_buffers);
970
    list_init(&kgem->active_buffers);
971
    list_init(&kgem->flushing);
971
    list_init(&kgem->flushing);
972
    list_init(&kgem->large);
972
    list_init(&kgem->large);
973
    list_init(&kgem->large_inactive);
973
    list_init(&kgem->large_inactive);
974
    list_init(&kgem->snoop);
974
    list_init(&kgem->snoop);
975
    list_init(&kgem->scanout);
975
    list_init(&kgem->scanout);
976
    for (i = 0; i < ARRAY_SIZE(kgem->pinned_batches); i++)
976
    for (i = 0; i < ARRAY_SIZE(kgem->pinned_batches); i++)
977
        list_init(&kgem->pinned_batches[i]);
977
        list_init(&kgem->pinned_batches[i]);
978
    for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++)
978
    for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++)
979
        list_init(&kgem->inactive[i]);
979
        list_init(&kgem->inactive[i]);
980
    for (i = 0; i < ARRAY_SIZE(kgem->active); i++) {
980
    for (i = 0; i < ARRAY_SIZE(kgem->active); i++) {
981
        for (j = 0; j < ARRAY_SIZE(kgem->active[i]); j++)
981
        for (j = 0; j < ARRAY_SIZE(kgem->active[i]); j++)
982
            list_init(&kgem->active[i][j]);
982
            list_init(&kgem->active[i][j]);
983
    }
983
    }
984
    for (i = 0; i < ARRAY_SIZE(kgem->vma); i++) {
984
    for (i = 0; i < ARRAY_SIZE(kgem->vma); i++) {
985
        for (j = 0; j < ARRAY_SIZE(kgem->vma[i].inactive); j++)
985
        for (j = 0; j < ARRAY_SIZE(kgem->vma[i].inactive); j++)
986
            list_init(&kgem->vma[i].inactive[j]);
986
            list_init(&kgem->vma[i].inactive[j]);
987
    }
987
    }
988
    kgem->vma[MAP_GTT].count = -MAX_GTT_VMA_CACHE;
988
    kgem->vma[MAP_GTT].count = -MAX_GTT_VMA_CACHE;
989
    kgem->vma[MAP_CPU].count = -MAX_CPU_VMA_CACHE;
989
    kgem->vma[MAP_CPU].count = -MAX_CPU_VMA_CACHE;
990
 
990
 
991
    kgem->has_blt = gem_param(kgem, LOCAL_I915_PARAM_HAS_BLT) > 0;
991
    kgem->has_blt = gem_param(kgem, LOCAL_I915_PARAM_HAS_BLT) > 0;
992
    DBG(("%s: has BLT ring? %d\n", __FUNCTION__,
992
    DBG(("%s: has BLT ring? %d\n", __FUNCTION__,
993
         kgem->has_blt));
993
         kgem->has_blt));
994
 
994
 
995
    kgem->has_relaxed_delta =
995
    kgem->has_relaxed_delta =
996
        gem_param(kgem, LOCAL_I915_PARAM_HAS_RELAXED_DELTA) > 0;
996
        gem_param(kgem, LOCAL_I915_PARAM_HAS_RELAXED_DELTA) > 0;
997
    DBG(("%s: has relaxed delta? %d\n", __FUNCTION__,
997
    DBG(("%s: has relaxed delta? %d\n", __FUNCTION__,
998
         kgem->has_relaxed_delta));
998
         kgem->has_relaxed_delta));
999
 
999
 
1000
    kgem->has_relaxed_fencing = test_has_relaxed_fencing(kgem);
1000
    kgem->has_relaxed_fencing = test_has_relaxed_fencing(kgem);
1001
    DBG(("%s: has relaxed fencing? %d\n", __FUNCTION__,
1001
    DBG(("%s: has relaxed fencing? %d\n", __FUNCTION__,
1002
         kgem->has_relaxed_fencing));
1002
         kgem->has_relaxed_fencing));
1003
 
1003
 
1004
    kgem->has_llc = test_has_llc(kgem);
1004
    kgem->has_llc = test_has_llc(kgem);
1005
    DBG(("%s: has shared last-level-cache? %d\n", __FUNCTION__,
1005
    DBG(("%s: has shared last-level-cache? %d\n", __FUNCTION__,
1006
         kgem->has_llc));
1006
         kgem->has_llc));
1007
 
1007
 
1008
	kgem->has_wt = test_has_wt(kgem);
1008
	kgem->has_wt = test_has_wt(kgem);
1009
	DBG(("%s: has write-through caching for scanouts? %d\n", __FUNCTION__,
1009
	DBG(("%s: has write-through caching for scanouts? %d\n", __FUNCTION__,
1010
	     kgem->has_wt));
1010
	     kgem->has_wt));
1011
 
1011
 
1012
	kgem->has_caching = test_has_caching(kgem);
1012
	kgem->has_caching = test_has_caching(kgem);
1013
    DBG(("%s: has set-cache-level? %d\n", __FUNCTION__,
1013
    DBG(("%s: has set-cache-level? %d\n", __FUNCTION__,
1014
	     kgem->has_caching));
1014
	     kgem->has_caching));
1015
 
1015
 
1016
    kgem->has_userptr = test_has_userptr(kgem);
1016
    kgem->has_userptr = test_has_userptr(kgem);
1017
    DBG(("%s: has userptr? %d\n", __FUNCTION__,
1017
    DBG(("%s: has userptr? %d\n", __FUNCTION__,
1018
         kgem->has_userptr));
1018
         kgem->has_userptr));
1019
 
1019
 
1020
	kgem->has_create2 = test_has_create2(kgem);
1020
	kgem->has_create2 = test_has_create2(kgem);
1021
	kgem->has_create2 = 0;
1021
	kgem->has_create2 = 0;
1022
	DBG(("%s: has create2? %d\n", __FUNCTION__,
1022
	DBG(("%s: has create2? %d\n", __FUNCTION__,
1023
	     kgem->has_create2));
1023
	     kgem->has_create2));
1024
 
1024
 
1025
    kgem->has_no_reloc = test_has_no_reloc(kgem);
1025
    kgem->has_no_reloc = test_has_no_reloc(kgem);
1026
    DBG(("%s: has no-reloc? %d\n", __FUNCTION__,
1026
    DBG(("%s: has no-reloc? %d\n", __FUNCTION__,
1027
         kgem->has_no_reloc));
1027
         kgem->has_no_reloc));
1028
 
1028
 
1029
    kgem->has_handle_lut = test_has_handle_lut(kgem);
1029
    kgem->has_handle_lut = test_has_handle_lut(kgem);
1030
    kgem->has_handle_lut = 0;
1030
    kgem->has_handle_lut = 0;
1031
    DBG(("%s: has handle-lut? %d\n", __FUNCTION__,
1031
    DBG(("%s: has handle-lut? %d\n", __FUNCTION__,
1032
         kgem->has_handle_lut));
1032
         kgem->has_handle_lut));
1033
 
1033
 
1034
    kgem->has_semaphores = false;
1034
    kgem->has_semaphores = false;
1035
    if (kgem->has_blt && test_has_semaphores_enabled(kgem))
1035
    if (kgem->has_blt && test_has_semaphores_enabled(kgem))
1036
        kgem->has_semaphores = true;
1036
        kgem->has_semaphores = true;
1037
    DBG(("%s: semaphores enabled? %d\n", __FUNCTION__,
1037
    DBG(("%s: semaphores enabled? %d\n", __FUNCTION__,
1038
         kgem->has_semaphores));
1038
         kgem->has_semaphores));
1039
 
1039
 
1040
    kgem->can_blt_cpu = gen >= 030;
1040
    kgem->can_blt_cpu = gen >= 030;
1041
    DBG(("%s: can blt to cpu? %d\n", __FUNCTION__,
1041
    DBG(("%s: can blt to cpu? %d\n", __FUNCTION__,
1042
         kgem->can_blt_cpu));
1042
         kgem->can_blt_cpu));
1043
 
1043
 
1044
    kgem->has_secure_batches = test_has_secure_batches(kgem);
1044
    kgem->has_secure_batches = test_has_secure_batches(kgem);
1045
    DBG(("%s: can use privileged batchbuffers? %d\n", __FUNCTION__,
1045
    DBG(("%s: can use privileged batchbuffers? %d\n", __FUNCTION__,
1046
         kgem->has_secure_batches));
1046
         kgem->has_secure_batches));
1047
 
1047
 
1048
    kgem->has_pinned_batches = test_has_pinned_batches(kgem);
1048
    kgem->has_pinned_batches = test_has_pinned_batches(kgem);
1049
    DBG(("%s: can use pinned batchbuffers (to avoid CS w/a)? %d\n", __FUNCTION__,
1049
    DBG(("%s: can use pinned batchbuffers (to avoid CS w/a)? %d\n", __FUNCTION__,
1050
         kgem->has_pinned_batches));
1050
         kgem->has_pinned_batches));
1051
 
1051
 
1052
    if (!is_hw_supported(kgem, dev)) {
1052
    if (!is_hw_supported(kgem, dev)) {
1053
        printf("Detected unsupported/dysfunctional hardware, disabling acceleration.\n");
1053
        printf("Detected unsupported/dysfunctional hardware, disabling acceleration.\n");
1054
        kgem->wedged = 1;
1054
        kgem->wedged = 1;
1055
    } else if (__kgem_throttle(kgem)) {
1055
    } else if (__kgem_throttle(kgem)) {
1056
        printf("Detected a hung GPU, disabling acceleration.\n");
1056
        printf("Detected a hung GPU, disabling acceleration.\n");
1057
        kgem->wedged = 1;
1057
        kgem->wedged = 1;
1058
    }
1058
    }
1059
 
1059
 
1060
    kgem->batch_size = ARRAY_SIZE(kgem->batch);
1060
    kgem->batch_size = ARRAY_SIZE(kgem->batch);
1061
    if (gen == 020 && !kgem->has_pinned_batches)
1061
    if (gen == 020 && !kgem->has_pinned_batches)
1062
        /* Limited to what we can pin */
1062
        /* Limited to what we can pin */
1063
        kgem->batch_size = 4*1024;
1063
        kgem->batch_size = 4*1024;
1064
    if (gen == 022)
1064
    if (gen == 022)
1065
        /* 865g cannot handle a batch spanning multiple pages */
1065
        /* 865g cannot handle a batch spanning multiple pages */
1066
        kgem->batch_size = PAGE_SIZE / sizeof(uint32_t);
1066
        kgem->batch_size = PAGE_SIZE / sizeof(uint32_t);
1067
    if ((gen >> 3) == 7)
1067
    if ((gen >> 3) == 7)
1068
        kgem->batch_size = 16*1024;
1068
        kgem->batch_size = 16*1024;
1069
    if (!kgem->has_relaxed_delta && kgem->batch_size > 4*1024)
1069
    if (!kgem->has_relaxed_delta && kgem->batch_size > 4*1024)
1070
        kgem->batch_size = 4*1024;
1070
        kgem->batch_size = 4*1024;
1071
 
1071
 
1072
    if (!kgem_init_pinned_batches(kgem) && gen == 020) {
1072
    if (!kgem_init_pinned_batches(kgem) && gen == 020) {
1073
        printf("Unable to reserve memory for GPU, disabling acceleration.\n");
1073
        printf("Unable to reserve memory for GPU, disabling acceleration.\n");
1074
        kgem->wedged = 1;
1074
        kgem->wedged = 1;
1075
    }
1075
    }
1076
 
1076
 
1077
    DBG(("%s: maximum batch size? %d\n", __FUNCTION__,
1077
    DBG(("%s: maximum batch size? %d\n", __FUNCTION__,
1078
         kgem->batch_size));
1078
         kgem->batch_size));
1079
 
1079
 
1080
	kgem->min_alignment = 4;
1080
	kgem->min_alignment = 4;
1081
    if (gen < 040)
1081
    if (gen < 040)
1082
        kgem->min_alignment = 64;
1082
        kgem->min_alignment = 64;
1083
 
1083
 
1084
    kgem->half_cpu_cache_pages = cpu_cache_size() >> 13;
1084
    kgem->half_cpu_cache_pages = cpu_cache_size() >> 13;
1085
	DBG(("%s: last-level cache size: %d bytes, threshold in pages: %d\n",
1085
	DBG(("%s: last-level cache size: %d bytes, threshold in pages: %d\n",
1086
	     __FUNCTION__, cpu_cache_size(), kgem->half_cpu_cache_pages));
1086
	     __FUNCTION__, cpu_cache_size(), kgem->half_cpu_cache_pages));
1087
 
1087
 
1088
    kgem->next_request = __kgem_request_alloc(kgem);
1088
    kgem->next_request = __kgem_request_alloc(kgem);
1089
 
1089
 
1090
    DBG(("%s: cpu bo enabled %d: llc? %d, set-cache-level? %d, userptr? %d\n", __FUNCTION__,
1090
    DBG(("%s: cpu bo enabled %d: llc? %d, set-cache-level? %d, userptr? %d\n", __FUNCTION__,
1091
	     !DBG_NO_CPU && (kgem->has_llc | kgem->has_userptr | kgem->has_caching),
1091
	     !DBG_NO_CPU && (kgem->has_llc | kgem->has_userptr | kgem->has_caching),
1092
	     kgem->has_llc, kgem->has_caching, kgem->has_userptr));
1092
	     kgem->has_llc, kgem->has_caching, kgem->has_userptr));
1093
 
1093
 
1094
    VG_CLEAR(aperture);
1094
    VG_CLEAR(aperture);
1095
    aperture.aper_size = 0;
1095
    aperture.aper_size = 0;
1096
	(void)drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
1096
	(void)drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
1097
    if (aperture.aper_size == 0)
1097
    if (aperture.aper_size == 0)
1098
        aperture.aper_size = 64*1024*1024;
1098
        aperture.aper_size = 64*1024*1024;
1099
 
1099
 
1100
    DBG(("%s: aperture size %lld, available now %lld\n",
1100
    DBG(("%s: aperture size %lld, available now %lld\n",
1101
         __FUNCTION__,
1101
         __FUNCTION__,
1102
         (long long)aperture.aper_size,
1102
         (long long)aperture.aper_size,
1103
         (long long)aperture.aper_available_size));
1103
         (long long)aperture.aper_available_size));
1104
 
1104
 
1105
    kgem->aperture_total = aperture.aper_size;
1105
    kgem->aperture_total = aperture.aper_size;
1106
    kgem->aperture_high = aperture.aper_size * 3/4;
1106
    kgem->aperture_high = aperture.aper_size * 3/4;
1107
    kgem->aperture_low = aperture.aper_size * 1/3;
1107
    kgem->aperture_low = aperture.aper_size * 1/3;
1108
    if (gen < 033) {
1108
    if (gen < 033) {
1109
        /* Severe alignment penalties */
1109
        /* Severe alignment penalties */
1110
        kgem->aperture_high /= 2;
1110
        kgem->aperture_high /= 2;
1111
        kgem->aperture_low /= 2;
1111
        kgem->aperture_low /= 2;
1112
    }
1112
    }
1113
    DBG(("%s: aperture low=%d [%d], high=%d [%d]\n", __FUNCTION__,
1113
    DBG(("%s: aperture low=%d [%d], high=%d [%d]\n", __FUNCTION__,
1114
         kgem->aperture_low, kgem->aperture_low / (1024*1024),
1114
         kgem->aperture_low, kgem->aperture_low / (1024*1024),
1115
         kgem->aperture_high, kgem->aperture_high / (1024*1024)));
1115
         kgem->aperture_high, kgem->aperture_high / (1024*1024)));
1116
 
1116
 
1117
    kgem->aperture_mappable = agp_aperture_size(dev, gen);
1117
    kgem->aperture_mappable = agp_aperture_size(dev, gen);
1118
    if (kgem->aperture_mappable == 0 ||
1118
    if (kgem->aperture_mappable == 0 ||
1119
        kgem->aperture_mappable > aperture.aper_size)
1119
        kgem->aperture_mappable > aperture.aper_size)
1120
        kgem->aperture_mappable = aperture.aper_size;
1120
        kgem->aperture_mappable = aperture.aper_size;
1121
    DBG(("%s: aperture mappable=%d [%d MiB]\n", __FUNCTION__,
1121
    DBG(("%s: aperture mappable=%d [%d MiB]\n", __FUNCTION__,
1122
         kgem->aperture_mappable, kgem->aperture_mappable / (1024*1024)));
1122
         kgem->aperture_mappable, kgem->aperture_mappable / (1024*1024)));
1123
 
1123
 
1124
    kgem->buffer_size = 64 * 1024;
1124
    kgem->buffer_size = 64 * 1024;
1125
    while (kgem->buffer_size < kgem->aperture_mappable >> 10)
1125
    while (kgem->buffer_size < kgem->aperture_mappable >> 10)
1126
        kgem->buffer_size *= 2;
1126
        kgem->buffer_size *= 2;
1127
    if (kgem->buffer_size >> 12 > kgem->half_cpu_cache_pages)
1127
    if (kgem->buffer_size >> 12 > kgem->half_cpu_cache_pages)
1128
        kgem->buffer_size = kgem->half_cpu_cache_pages << 12;
1128
        kgem->buffer_size = kgem->half_cpu_cache_pages << 12;
1129
	kgem->buffer_size = 1 << __fls(kgem->buffer_size);
1129
	kgem->buffer_size = 1 << __fls(kgem->buffer_size);
1130
    DBG(("%s: buffer size=%d [%d KiB]\n", __FUNCTION__,
1130
    DBG(("%s: buffer size=%d [%d KiB]\n", __FUNCTION__,
1131
         kgem->buffer_size, kgem->buffer_size / 1024));
1131
         kgem->buffer_size, kgem->buffer_size / 1024));
1132
	assert(kgem->buffer_size);
1132
	assert(kgem->buffer_size);
1133
 
1133
 
1134
    kgem->max_object_size = 3 * (kgem->aperture_high >> 12) << 10;
1134
    kgem->max_object_size = 3 * (kgem->aperture_high >> 12) << 10;
1135
    kgem->max_gpu_size = kgem->max_object_size;
1135
    kgem->max_gpu_size = kgem->max_object_size;
1136
	if (!kgem->has_llc && kgem->max_gpu_size > MAX_CACHE_SIZE)
1136
	if (!kgem->has_llc && kgem->max_gpu_size > MAX_CACHE_SIZE)
1137
        kgem->max_gpu_size = MAX_CACHE_SIZE;
1137
        kgem->max_gpu_size = MAX_CACHE_SIZE;
1138
 
1138
 
1139
    totalram = total_ram_size();
1139
    totalram = total_ram_size();
1140
    if (totalram == 0) {
1140
    if (totalram == 0) {
1141
        DBG(("%s: total ram size unknown, assuming maximum of total aperture\n",
1141
        DBG(("%s: total ram size unknown, assuming maximum of total aperture\n",
1142
             __FUNCTION__));
1142
             __FUNCTION__));
1143
        totalram = kgem->aperture_total;
1143
        totalram = kgem->aperture_total;
1144
    }
1144
    }
1145
	DBG(("%s: total ram=%ld\n", __FUNCTION__, (long)totalram));
1145
	DBG(("%s: total ram=%ld\n", __FUNCTION__, (long)totalram));
1146
    if (kgem->max_object_size > totalram / 2)
1146
    if (kgem->max_object_size > totalram / 2)
1147
        kgem->max_object_size = totalram / 2;
1147
        kgem->max_object_size = totalram / 2;
1148
    if (kgem->max_gpu_size > totalram / 4)
1148
    if (kgem->max_gpu_size > totalram / 4)
1149
        kgem->max_gpu_size = totalram / 4;
1149
        kgem->max_gpu_size = totalram / 4;
1150
 
1150
 
1151
    kgem->max_cpu_size = kgem->max_object_size;
1151
    kgem->max_cpu_size = kgem->max_object_size;
1152
 
1152
 
1153
    half_gpu_max = kgem->max_gpu_size / 2;
1153
    half_gpu_max = kgem->max_gpu_size / 2;
1154
    kgem->max_copy_tile_size = (MAX_CACHE_SIZE + 1)/2;
1154
    kgem->max_copy_tile_size = (MAX_CACHE_SIZE + 1)/2;
1155
    if (kgem->max_copy_tile_size > half_gpu_max)
1155
    if (kgem->max_copy_tile_size > half_gpu_max)
1156
        kgem->max_copy_tile_size = half_gpu_max;
1156
        kgem->max_copy_tile_size = half_gpu_max;
1157
 
1157
 
1158
    if (kgem->has_llc)
1158
    if (kgem->has_llc)
1159
        kgem->max_upload_tile_size = kgem->max_copy_tile_size;
1159
        kgem->max_upload_tile_size = kgem->max_copy_tile_size;
1160
    else
1160
    else
1161
        kgem->max_upload_tile_size = kgem->aperture_mappable / 4;
1161
        kgem->max_upload_tile_size = kgem->aperture_mappable / 4;
1162
    if (kgem->max_upload_tile_size > half_gpu_max)
1162
    if (kgem->max_upload_tile_size > half_gpu_max)
1163
        kgem->max_upload_tile_size = half_gpu_max;
1163
        kgem->max_upload_tile_size = half_gpu_max;
1164
	if (kgem->max_upload_tile_size > kgem->aperture_high/2)
1164
	if (kgem->max_upload_tile_size > kgem->aperture_high/2)
1165
		kgem->max_upload_tile_size = kgem->aperture_high/2;
1165
		kgem->max_upload_tile_size = kgem->aperture_high/2;
1166
	if (kgem->max_upload_tile_size > kgem->aperture_low)
1166
	if (kgem->max_upload_tile_size > kgem->aperture_low)
1167
		kgem->max_upload_tile_size = kgem->aperture_low;
1167
		kgem->max_upload_tile_size = kgem->aperture_low;
1168
	if (kgem->max_upload_tile_size < 16*PAGE_SIZE)
1168
	if (kgem->max_upload_tile_size < 16*PAGE_SIZE)
1169
		kgem->max_upload_tile_size = 16*PAGE_SIZE;
1169
		kgem->max_upload_tile_size = 16*PAGE_SIZE;
1170
 
1170
 
1171
    kgem->large_object_size = MAX_CACHE_SIZE;
1171
    kgem->large_object_size = MAX_CACHE_SIZE;
1172
	if (kgem->large_object_size > half_gpu_max)
1172
	if (kgem->large_object_size > half_gpu_max)
1173
		kgem->large_object_size = half_gpu_max;
1173
		kgem->large_object_size = half_gpu_max;
1174
	if (kgem->max_copy_tile_size > kgem->aperture_high/2)
1174
	if (kgem->max_copy_tile_size > kgem->aperture_high/2)
1175
		kgem->max_copy_tile_size = kgem->aperture_high/2;
1175
		kgem->max_copy_tile_size = kgem->aperture_high/2;
1176
	if (kgem->max_copy_tile_size > kgem->aperture_low)
1176
	if (kgem->max_copy_tile_size > kgem->aperture_low)
1177
		kgem->max_copy_tile_size = kgem->aperture_low;
1177
		kgem->max_copy_tile_size = kgem->aperture_low;
1178
	if (kgem->max_copy_tile_size < 16*PAGE_SIZE)
1178
	if (kgem->max_copy_tile_size < 16*PAGE_SIZE)
1179
		kgem->max_copy_tile_size = 16*PAGE_SIZE;
1179
		kgem->max_copy_tile_size = 16*PAGE_SIZE;
1180
 
1180
 
1181
	if (kgem->has_llc | kgem->has_caching | kgem->has_userptr) {
1181
	if (kgem->has_llc | kgem->has_caching | kgem->has_userptr) {
1182
        if (kgem->large_object_size > kgem->max_cpu_size)
1182
        if (kgem->large_object_size > kgem->max_cpu_size)
1183
            kgem->large_object_size = kgem->max_cpu_size;
1183
            kgem->large_object_size = kgem->max_cpu_size;
1184
    } else
1184
    } else
1185
        kgem->max_cpu_size = 0;
1185
        kgem->max_cpu_size = 0;
1186
    if (DBG_NO_CPU)
1186
    if (DBG_NO_CPU)
1187
        kgem->max_cpu_size = 0;
1187
        kgem->max_cpu_size = 0;
1188
 
1188
 
1189
    DBG(("%s: maximum object size=%d\n",
1189
    DBG(("%s: maximum object size=%d\n",
1190
         __FUNCTION__, kgem->max_object_size));
1190
         __FUNCTION__, kgem->max_object_size));
1191
    DBG(("%s: large object thresold=%d\n",
1191
    DBG(("%s: large object thresold=%d\n",
1192
         __FUNCTION__, kgem->large_object_size));
1192
         __FUNCTION__, kgem->large_object_size));
1193
    DBG(("%s: max object sizes (gpu=%d, cpu=%d, tile upload=%d, copy=%d)\n",
1193
    DBG(("%s: max object sizes (gpu=%d, cpu=%d, tile upload=%d, copy=%d)\n",
1194
         __FUNCTION__,
1194
         __FUNCTION__,
1195
         kgem->max_gpu_size, kgem->max_cpu_size,
1195
         kgem->max_gpu_size, kgem->max_cpu_size,
1196
         kgem->max_upload_tile_size, kgem->max_copy_tile_size));
1196
         kgem->max_upload_tile_size, kgem->max_copy_tile_size));
1197
 
1197
 
1198
    /* Convert the aperture thresholds to pages */
1198
    /* Convert the aperture thresholds to pages */
1199
    kgem->aperture_low /= PAGE_SIZE;
1199
    kgem->aperture_low /= PAGE_SIZE;
1200
    kgem->aperture_high /= PAGE_SIZE;
1200
    kgem->aperture_high /= PAGE_SIZE;
1201
 
1201
 
1202
    kgem->fence_max = gem_param(kgem, I915_PARAM_NUM_FENCES_AVAIL) - 2;
1202
    kgem->fence_max = gem_param(kgem, I915_PARAM_NUM_FENCES_AVAIL) - 2;
1203
    if ((int)kgem->fence_max < 0)
1203
    if ((int)kgem->fence_max < 0)
1204
        kgem->fence_max = 5; /* minimum safe value for all hw */
1204
        kgem->fence_max = 5; /* minimum safe value for all hw */
1205
    DBG(("%s: max fences=%d\n", __FUNCTION__, kgem->fence_max));
1205
    DBG(("%s: max fences=%d\n", __FUNCTION__, kgem->fence_max));
1206
 
1206
 
1207
    kgem->batch_flags_base = 0;
1207
    kgem->batch_flags_base = 0;
1208
    if (kgem->has_no_reloc)
1208
    if (kgem->has_no_reloc)
1209
        kgem->batch_flags_base |= LOCAL_I915_EXEC_NO_RELOC;
1209
        kgem->batch_flags_base |= LOCAL_I915_EXEC_NO_RELOC;
1210
    if (kgem->has_handle_lut)
1210
    if (kgem->has_handle_lut)
1211
        kgem->batch_flags_base |= LOCAL_I915_EXEC_HANDLE_LUT;
1211
        kgem->batch_flags_base |= LOCAL_I915_EXEC_HANDLE_LUT;
1212
    if (kgem->has_pinned_batches)
1212
    if (kgem->has_pinned_batches)
1213
        kgem->batch_flags_base |= LOCAL_I915_EXEC_IS_PINNED;
1213
        kgem->batch_flags_base |= LOCAL_I915_EXEC_IS_PINNED;
1214
}
1214
}
1215
 
1215
 
1216
/* XXX hopefully a good approximation */
1216
/* XXX hopefully a good approximation */
1217
uint32_t kgem_get_unique_id(struct kgem *kgem)
1217
uint32_t kgem_get_unique_id(struct kgem *kgem)
1218
{
1218
{
1219
	uint32_t id;
1219
	uint32_t id;
1220
	id = ++kgem->unique_id;
1220
	id = ++kgem->unique_id;
1221
	if (id == 0)
1221
	if (id == 0)
1222
		id = ++kgem->unique_id;
1222
		id = ++kgem->unique_id;
1223
	return id;
1223
	return id;
1224
}
1224
}
1225
 
1225
 
1226
inline static uint32_t kgem_pitch_alignment(struct kgem *kgem, unsigned flags)
1226
inline static uint32_t kgem_pitch_alignment(struct kgem *kgem, unsigned flags)
1227
{
1227
{
1228
	if (flags & CREATE_PRIME)
1228
	if (flags & CREATE_PRIME)
1229
		return 256;
1229
		return 256;
1230
	if (flags & CREATE_SCANOUT)
1230
	if (flags & CREATE_SCANOUT)
1231
		return 64;
1231
		return 64;
1232
	return kgem->min_alignment;
1232
	return kgem->min_alignment;
1233
}
1233
}
1234
 
1234
 
1235
void kgem_get_tile_size(struct kgem *kgem, int tiling,
1235
void kgem_get_tile_size(struct kgem *kgem, int tiling,
1236
			int *tile_width, int *tile_height, int *tile_size)
1236
			int *tile_width, int *tile_height, int *tile_size)
1237
{
1237
{
1238
	if (kgem->gen <= 030) {
1238
	if (kgem->gen <= 030) {
1239
		if (tiling) {
1239
		if (tiling) {
1240
			if (kgem->gen < 030) {
1240
			if (kgem->gen < 030) {
1241
				*tile_width = 128;
1241
				*tile_width = 128;
1242
				*tile_height = 16;
1242
				*tile_height = 16;
1243
				*tile_size = 2048;
1243
				*tile_size = 2048;
1244
			} else {
1244
			} else {
1245
				*tile_width = 512;
1245
				*tile_width = 512;
1246
				*tile_height = 8;
1246
				*tile_height = 8;
1247
				*tile_size = 4096;
1247
				*tile_size = 4096;
1248
			}
1248
			}
1249
		} else {
1249
		} else {
1250
			*tile_width = 1;
1250
			*tile_width = 1;
1251
			*tile_height = 1;
1251
			*tile_height = 1;
1252
			*tile_size = 1;
1252
			*tile_size = 1;
1253
		}
1253
		}
1254
	} else switch (tiling) {
1254
	} else switch (tiling) {
1255
	default:
1255
	default:
1256
	case I915_TILING_NONE:
1256
	case I915_TILING_NONE:
1257
		*tile_width = 1;
1257
		*tile_width = 1;
1258
		*tile_height = 1;
1258
		*tile_height = 1;
1259
		*tile_size = 1;
1259
		*tile_size = 1;
1260
		break;
1260
		break;
1261
	case I915_TILING_X:
1261
	case I915_TILING_X:
1262
		*tile_width = 512;
1262
		*tile_width = 512;
1263
		*tile_height = 8;
1263
		*tile_height = 8;
1264
		*tile_size = 4096;
1264
		*tile_size = 4096;
1265
		break;
1265
		break;
1266
	case I915_TILING_Y:
1266
	case I915_TILING_Y:
1267
		*tile_width = 128;
1267
		*tile_width = 128;
1268
		*tile_height = 32;
1268
		*tile_height = 32;
1269
		*tile_size = 4096;
1269
		*tile_size = 4096;
1270
		break;
1270
		break;
1271
	}
1271
	}
1272
}
1272
}
1273
 
1273
 
1274
uint32_t kgem_surface_size(struct kgem *kgem,
1274
uint32_t kgem_surface_size(struct kgem *kgem,
1275
				  bool relaxed_fencing,
1275
				  bool relaxed_fencing,
1276
				  unsigned flags,
1276
				  unsigned flags,
1277
				  uint32_t width,
1277
				  uint32_t width,
1278
				  uint32_t height,
1278
				  uint32_t height,
1279
				  uint32_t bpp,
1279
				  uint32_t bpp,
1280
				  uint32_t tiling,
1280
				  uint32_t tiling,
1281
				  uint32_t *pitch)
1281
				  uint32_t *pitch)
1282
{
1282
{
1283
	uint32_t tile_width, tile_height;
1283
	uint32_t tile_width, tile_height;
1284
	uint32_t size;
1284
	uint32_t size;
1285
 
1285
 
1286
	assert(width <= MAXSHORT);
1286
	assert(width <= MAXSHORT);
1287
	assert(height <= MAXSHORT);
1287
	assert(height <= MAXSHORT);
1288
	assert(bpp >= 8);
1288
	assert(bpp >= 8);
1289
 
1289
 
1290
	if (kgem->gen <= 030) {
1290
	if (kgem->gen <= 030) {
1291
		if (tiling) {
1291
		if (tiling) {
1292
			if (kgem->gen < 030) {
1292
			if (kgem->gen < 030) {
1293
				tile_width = 128;
1293
				tile_width = 128;
1294
				tile_height = 32;
1294
				tile_height = 32;
1295
			} else {
1295
			} else {
1296
				tile_width = 512;
1296
				tile_width = 512;
1297
				tile_height = 16;
1297
				tile_height = 16;
1298
			}
1298
			}
1299
		} else {
1299
		} else {
1300
			tile_width = 2 * bpp >> 3;
1300
			tile_width = 2 * bpp >> 3;
1301
			tile_width = ALIGN(tile_width,
1301
			tile_width = ALIGN(tile_width,
1302
					   kgem_pitch_alignment(kgem, flags));
1302
					   kgem_pitch_alignment(kgem, flags));
1303
			tile_height = 2;
1303
			tile_height = 2;
1304
		}
1304
		}
1305
	} else switch (tiling) {
1305
	} else switch (tiling) {
1306
	default:
1306
	default:
1307
	case I915_TILING_NONE:
1307
	case I915_TILING_NONE:
1308
		tile_width = 2 * bpp >> 3;
1308
		tile_width = 2 * bpp >> 3;
1309
		tile_width = ALIGN(tile_width,
1309
		tile_width = ALIGN(tile_width,
1310
				   kgem_pitch_alignment(kgem, flags));
1310
				   kgem_pitch_alignment(kgem, flags));
1311
		tile_height = 2;
1311
		tile_height = 2;
1312
		break;
1312
		break;
1313
 
1313
 
1314
		/* XXX align to an even tile row */
1314
		/* XXX align to an even tile row */
1315
	case I915_TILING_X:
1315
	case I915_TILING_X:
1316
		tile_width = 512;
1316
		tile_width = 512;
1317
		tile_height = 16;
1317
		tile_height = 16;
1318
		break;
1318
		break;
1319
	case I915_TILING_Y:
1319
	case I915_TILING_Y:
1320
		tile_width = 128;
1320
		tile_width = 128;
1321
		tile_height = 64;
1321
		tile_height = 64;
1322
		break;
1322
		break;
1323
	}
1323
	}
1324
 
1324
 
1325
	*pitch = ALIGN(width * bpp / 8, tile_width);
1325
	*pitch = ALIGN(width * bpp / 8, tile_width);
1326
	height = ALIGN(height, tile_height);
1326
	height = ALIGN(height, tile_height);
1327
	if (kgem->gen >= 040)
1327
	if (kgem->gen >= 040)
1328
		return PAGE_ALIGN(*pitch * height);
1328
		return PAGE_ALIGN(*pitch * height);
1329
 
1329
 
1330
	/* If it is too wide for the blitter, don't even bother.  */
1330
	/* If it is too wide for the blitter, don't even bother.  */
1331
	if (tiling != I915_TILING_NONE) {
1331
	if (tiling != I915_TILING_NONE) {
1332
		if (*pitch > 8192)
1332
		if (*pitch > 8192)
1333
			return 0;
1333
			return 0;
1334
 
1334
 
1335
		for (size = tile_width; size < *pitch; size <<= 1)
1335
		for (size = tile_width; size < *pitch; size <<= 1)
1336
			;
1336
			;
1337
		*pitch = size;
1337
		*pitch = size;
1338
	} else {
1338
	} else {
1339
		if (*pitch >= 32768)
1339
		if (*pitch >= 32768)
1340
			return 0;
1340
			return 0;
1341
	}
1341
	}
1342
 
1342
 
1343
	size = *pitch * height;
1343
	size = *pitch * height;
1344
	if (relaxed_fencing || tiling == I915_TILING_NONE)
1344
	if (relaxed_fencing || tiling == I915_TILING_NONE)
1345
		return PAGE_ALIGN(size);
1345
		return PAGE_ALIGN(size);
1346
 
1346
 
1347
	/*  We need to allocate a pot fence region for a tiled buffer. */
1347
	/*  We need to allocate a pot fence region for a tiled buffer. */
1348
	if (kgem->gen < 030)
1348
	if (kgem->gen < 030)
1349
		tile_width = 512 * 1024;
1349
		tile_width = 512 * 1024;
1350
	else
1350
	else
1351
		tile_width = 1024 * 1024;
1351
		tile_width = 1024 * 1024;
1352
	while (tile_width < size)
1352
	while (tile_width < size)
1353
		tile_width *= 2;
1353
		tile_width *= 2;
1354
	return tile_width;
1354
	return tile_width;
1355
}
1355
}
1356
 
1356
 
1357
static uint32_t kgem_aligned_height(struct kgem *kgem,
1357
static uint32_t kgem_aligned_height(struct kgem *kgem,
1358
				    uint32_t height, uint32_t tiling)
1358
				    uint32_t height, uint32_t tiling)
1359
{
1359
{
1360
	uint32_t tile_height;
1360
	uint32_t tile_height;
1361
 
1361
 
1362
	if (kgem->gen <= 030) {
1362
	if (kgem->gen <= 030) {
1363
		tile_height = tiling ? kgem->gen < 030 ? 32 : 16 : 1;
1363
		tile_height = tiling ? kgem->gen < 030 ? 32 : 16 : 1;
1364
	} else switch (tiling) {
1364
	} else switch (tiling) {
1365
		/* XXX align to an even tile row */
1365
		/* XXX align to an even tile row */
1366
	default:
1366
	default:
1367
	case I915_TILING_NONE:
1367
	case I915_TILING_NONE:
1368
		tile_height = 1;
1368
		tile_height = 1;
1369
		break;
1369
		break;
1370
	case I915_TILING_X:
1370
	case I915_TILING_X:
1371
		tile_height = 16;
1371
		tile_height = 16;
1372
		break;
1372
		break;
1373
	case I915_TILING_Y:
1373
	case I915_TILING_Y:
1374
		tile_height = 64;
1374
		tile_height = 64;
1375
		break;
1375
		break;
1376
	}
1376
	}
1377
 
1377
 
1378
	return ALIGN(height, tile_height);
1378
	return ALIGN(height, tile_height);
1379
}
1379
}
1380
 
1380
 
1381
static struct drm_i915_gem_exec_object2 *
1381
static struct drm_i915_gem_exec_object2 *
1382
kgem_add_handle(struct kgem *kgem, struct kgem_bo *bo)
1382
kgem_add_handle(struct kgem *kgem, struct kgem_bo *bo)
1383
{
1383
{
1384
	struct drm_i915_gem_exec_object2 *exec;
1384
	struct drm_i915_gem_exec_object2 *exec;
1385
 
1385
 
1386
	DBG(("%s: handle=%d, index=%d\n",
1386
	DBG(("%s: handle=%d, index=%d\n",
1387
	     __FUNCTION__, bo->handle, kgem->nexec));
1387
	     __FUNCTION__, bo->handle, kgem->nexec));
1388
 
1388
 
1389
	assert(kgem->nexec < ARRAY_SIZE(kgem->exec));
1389
	assert(kgem->nexec < ARRAY_SIZE(kgem->exec));
1390
	bo->target_handle = kgem->has_handle_lut ? kgem->nexec : bo->handle;
1390
	bo->target_handle = kgem->has_handle_lut ? kgem->nexec : bo->handle;
1391
	exec = memset(&kgem->exec[kgem->nexec++], 0, sizeof(*exec));
1391
	exec = memset(&kgem->exec[kgem->nexec++], 0, sizeof(*exec));
1392
	exec->handle = bo->handle;
1392
	exec->handle = bo->handle;
1393
	exec->offset = bo->presumed_offset;
1393
	exec->offset = bo->presumed_offset;
1394
 
1394
 
1395
	kgem->aperture += num_pages(bo);
1395
	kgem->aperture += num_pages(bo);
1396
 
1396
 
1397
	return exec;
1397
	return exec;
1398
}
1398
}
1399
 
1399
 
1400
static void kgem_add_bo(struct kgem *kgem, struct kgem_bo *bo)
1400
static void kgem_add_bo(struct kgem *kgem, struct kgem_bo *bo)
1401
{
1401
{
1402
	bo->exec = kgem_add_handle(kgem, bo);
1402
	bo->exec = kgem_add_handle(kgem, bo);
1403
	bo->rq = MAKE_REQUEST(kgem->next_request, kgem->ring);
1403
	bo->rq = MAKE_REQUEST(kgem->next_request, kgem->ring);
1404
 
1404
 
1405
	list_move_tail(&bo->request, &kgem->next_request->buffers);
1405
	list_move_tail(&bo->request, &kgem->next_request->buffers);
1406
 
1406
 
1407
	/* XXX is it worth working around gcc here? */
1407
	/* XXX is it worth working around gcc here? */
1408
	kgem->flush |= bo->flush;
1408
	kgem->flush |= bo->flush;
1409
}
1409
}
1410
 
1410
 
1411
static uint32_t kgem_end_batch(struct kgem *kgem)
1411
static uint32_t kgem_end_batch(struct kgem *kgem)
1412
{
1412
{
1413
	kgem->batch[kgem->nbatch++] = MI_BATCH_BUFFER_END;
1413
	kgem->batch[kgem->nbatch++] = MI_BATCH_BUFFER_END;
1414
	if (kgem->nbatch & 1)
1414
	if (kgem->nbatch & 1)
1415
		kgem->batch[kgem->nbatch++] = MI_NOOP;
1415
		kgem->batch[kgem->nbatch++] = MI_NOOP;
1416
 
1416
 
1417
	return kgem->nbatch;
1417
	return kgem->nbatch;
1418
}
1418
}
1419
 
1419
 
1420
static void kgem_fixup_self_relocs(struct kgem *kgem, struct kgem_bo *bo)
1420
static void kgem_fixup_self_relocs(struct kgem *kgem, struct kgem_bo *bo)
1421
{
1421
{
1422
	int n;
1422
	int n;
1423
 
1423
 
1424
	assert(kgem->nreloc__self <= 256);
1424
	assert(kgem->nreloc__self <= 256);
1425
	if (kgem->nreloc__self == 0)
1425
	if (kgem->nreloc__self == 0)
1426
		return;
1426
		return;
1427
 
1427
 
1428
	for (n = 0; n < kgem->nreloc__self; n++) {
1428
	for (n = 0; n < kgem->nreloc__self; n++) {
1429
		int i = kgem->reloc__self[n];
1429
		int i = kgem->reloc__self[n];
1430
		assert(kgem->reloc[i].target_handle == ~0U);
1430
		assert(kgem->reloc[i].target_handle == ~0U);
1431
		kgem->reloc[i].target_handle = bo->target_handle;
1431
		kgem->reloc[i].target_handle = bo->target_handle;
1432
		kgem->reloc[i].presumed_offset = bo->presumed_offset;
1432
		kgem->reloc[i].presumed_offset = bo->presumed_offset;
1433
		kgem->batch[kgem->reloc[i].offset/sizeof(kgem->batch[0])] =
1433
		kgem->batch[kgem->reloc[i].offset/sizeof(kgem->batch[0])] =
1434
			kgem->reloc[i].delta + bo->presumed_offset;
1434
			kgem->reloc[i].delta + bo->presumed_offset;
1435
	}
1435
	}
1436
 
1436
 
1437
	if (n == 256) {
1437
	if (n == 256) {
1438
		for (n = kgem->reloc__self[255]; n < kgem->nreloc; n++) {
1438
		for (n = kgem->reloc__self[255]; n < kgem->nreloc; n++) {
1439
			if (kgem->reloc[n].target_handle == ~0U) {
1439
			if (kgem->reloc[n].target_handle == ~0U) {
1440
				kgem->reloc[n].target_handle = bo->target_handle;
1440
				kgem->reloc[n].target_handle = bo->target_handle;
1441
				kgem->reloc[n].presumed_offset = bo->presumed_offset;
1441
				kgem->reloc[n].presumed_offset = bo->presumed_offset;
1442
				kgem->batch[kgem->reloc[n].offset/sizeof(kgem->batch[0])] =
1442
				kgem->batch[kgem->reloc[n].offset/sizeof(kgem->batch[0])] =
1443
					kgem->reloc[n].delta + bo->presumed_offset;
1443
					kgem->reloc[n].delta + bo->presumed_offset;
1444
			}
1444
			}
1445
		}
1445
		}
1446
 
1446
 
1447
	}
1447
	}
1448
 
1448
 
1449
}
1449
}
1450
 
1450
 
1451
static void kgem_bo_binding_free(struct kgem *kgem, struct kgem_bo *bo)
1451
static void kgem_bo_binding_free(struct kgem *kgem, struct kgem_bo *bo)
1452
{
1452
{
1453
	struct kgem_bo_binding *b;
1453
	struct kgem_bo_binding *b;
1454
 
1454
 
1455
	b = bo->binding.next;
1455
	b = bo->binding.next;
1456
	while (b) {
1456
	while (b) {
1457
		struct kgem_bo_binding *next = b->next;
1457
		struct kgem_bo_binding *next = b->next;
1458
		free (b);
1458
		free (b);
1459
		b = next;
1459
		b = next;
1460
	}
1460
	}
1461
}
1461
}
1462
 
1462
 
1463
static void kgem_bo_release_map(struct kgem *kgem, struct kgem_bo *bo)
1463
static void kgem_bo_release_map(struct kgem *kgem, struct kgem_bo *bo)
1464
{
1464
{
1465
	int type = IS_CPU_MAP(bo->map);
1465
	int type = IS_CPU_MAP(bo->map);
1466
 
1466
 
1467
	assert(!IS_USER_MAP(bo->map));
1467
	assert(!IS_USER_MAP(bo->map));
1468
 
1468
 
1469
	DBG(("%s: releasing %s vma for handle=%d, count=%d\n",
1469
	DBG(("%s: releasing %s vma for handle=%d, count=%d\n",
1470
	     __FUNCTION__, type ? "CPU" : "GTT",
1470
	     __FUNCTION__, type ? "CPU" : "GTT",
1471
	     bo->handle, kgem->vma[type].count));
1471
	     bo->handle, kgem->vma[type].count));
1472
 
1472
 
1473
	VG(if (type) VALGRIND_MAKE_MEM_NOACCESS(MAP(bo->map), bytes(bo)));
1473
	VG(if (type) VALGRIND_MAKE_MEM_NOACCESS(MAP(bo->map), bytes(bo)));
1474
	user_free(MAP(bo->map));
1474
	user_free(MAP(bo->map));
1475
	bo->map = NULL;
1475
	bo->map = NULL;
1476
 
1476
 
1477
	if (!list_is_empty(&bo->vma)) {
1477
	if (!list_is_empty(&bo->vma)) {
1478
		list_del(&bo->vma);
1478
		list_del(&bo->vma);
1479
		kgem->vma[type].count--;
1479
		kgem->vma[type].count--;
1480
	}
1480
	}
1481
}
1481
}
1482
 
1482
 
1483
static void kgem_bo_free(struct kgem *kgem, struct kgem_bo *bo)
1483
static void kgem_bo_free(struct kgem *kgem, struct kgem_bo *bo)
1484
{
1484
{
1485
	DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
1485
	DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
1486
	assert(bo->refcnt == 0);
1486
	assert(bo->refcnt == 0);
1487
	assert(bo->proxy == NULL);
1487
	assert(bo->proxy == NULL);
1488
	assert(bo->exec == NULL);
1488
	assert(bo->exec == NULL);
1489
	assert(!bo->snoop || bo->rq == NULL);
1489
	assert(!bo->snoop || bo->rq == NULL);
1490
 
1490
 
1491
#ifdef DEBUG_MEMORY
1491
#ifdef DEBUG_MEMORY
1492
	kgem->debug_memory.bo_allocs--;
1492
	kgem->debug_memory.bo_allocs--;
1493
	kgem->debug_memory.bo_bytes -= bytes(bo);
1493
	kgem->debug_memory.bo_bytes -= bytes(bo);
1494
#endif
1494
#endif
1495
 
1495
 
1496
	kgem_bo_binding_free(kgem, bo);
1496
	kgem_bo_binding_free(kgem, bo);
1497
 
1497
 
1498
	if (IS_USER_MAP(bo->map)) {
1498
	if (IS_USER_MAP(bo->map)) {
1499
		assert(bo->rq == NULL);
1499
		assert(bo->rq == NULL);
1500
		assert(!__kgem_busy(kgem, bo->handle));
1500
		assert(!__kgem_busy(kgem, bo->handle));
1501
		assert(MAP(bo->map) != bo || bo->io || bo->flush);
1501
		assert(MAP(bo->map) != bo || bo->io || bo->flush);
1502
		if (!(bo->io || bo->flush)) {
1502
		if (!(bo->io || bo->flush)) {
1503
			DBG(("%s: freeing snooped base\n", __FUNCTION__));
1503
			DBG(("%s: freeing snooped base\n", __FUNCTION__));
1504
			assert(bo != MAP(bo->map));
1504
			assert(bo != MAP(bo->map));
1505
			free(MAP(bo->map));
1505
			free(MAP(bo->map));
1506
		}
1506
		}
1507
		bo->map = NULL;
1507
		bo->map = NULL;
1508
	}
1508
	}
1509
	if (bo->map)
1509
	if (bo->map)
1510
		kgem_bo_release_map(kgem, bo);
1510
		kgem_bo_release_map(kgem, bo);
1511
	assert(list_is_empty(&bo->vma));
1511
	assert(list_is_empty(&bo->vma));
1512
	assert(bo->map == NULL);
1512
	assert(bo->map == NULL);
1513
 
1513
 
1514
	_list_del(&bo->list);
1514
	_list_del(&bo->list);
1515
	_list_del(&bo->request);
1515
	_list_del(&bo->request);
1516
	gem_close(kgem->fd, bo->handle);
1516
	gem_close(kgem->fd, bo->handle);
1517
 
1517
 
1518
	if (!bo->io) {
1518
	if (!bo->io) {
1519
		*(struct kgem_bo **)bo = __kgem_freed_bo;
1519
		*(struct kgem_bo **)bo = __kgem_freed_bo;
1520
		__kgem_freed_bo = bo;
1520
		__kgem_freed_bo = bo;
1521
	} else
1521
	} else
1522
		free(bo);
1522
		free(bo);
1523
}
1523
}
1524
 
1524
 
1525
inline static void kgem_bo_move_to_inactive(struct kgem *kgem,
1525
inline static void kgem_bo_move_to_inactive(struct kgem *kgem,
1526
					    struct kgem_bo *bo)
1526
					    struct kgem_bo *bo)
1527
{
1527
{
1528
	DBG(("%s: moving handle=%d to inactive\n", __FUNCTION__, bo->handle));
1528
	DBG(("%s: moving handle=%d to inactive\n", __FUNCTION__, bo->handle));
1529
 
1529
 
1530
	assert(bo->refcnt == 0);
1530
	assert(bo->refcnt == 0);
1531
	assert(bo->reusable);
1531
	assert(bo->reusable);
1532
	assert(bo->rq == NULL);
1532
	assert(bo->rq == NULL);
1533
	assert(bo->exec == NULL);
1533
	assert(bo->exec == NULL);
1534
	assert(bo->domain != DOMAIN_GPU);
1534
	assert(bo->domain != DOMAIN_GPU);
1535
	assert(!bo->proxy);
1535
	assert(!bo->proxy);
1536
	assert(!bo->io);
1536
	assert(!bo->io);
1537
	assert(!bo->scanout);
1537
	assert(!bo->scanout);
1538
	assert(!bo->snoop);
1538
	assert(!bo->snoop);
1539
	assert(!bo->flush);
1539
	assert(!bo->flush);
1540
	assert(!bo->needs_flush);
1540
	assert(!bo->needs_flush);
1541
	assert(list_is_empty(&bo->vma));
1541
	assert(list_is_empty(&bo->vma));
1542
	assert_tiling(kgem, bo);
1542
	assert_tiling(kgem, bo);
1543
	ASSERT_IDLE(kgem, bo->handle);
1543
	ASSERT_IDLE(kgem, bo->handle);
1544
 
1544
 
1545
	kgem->need_expire = true;
1545
	kgem->need_expire = true;
1546
 
1546
 
1547
	if (bucket(bo) >= NUM_CACHE_BUCKETS) {
1547
	if (bucket(bo) >= NUM_CACHE_BUCKETS) {
1548
		list_move(&bo->list, &kgem->large_inactive);
1548
		list_move(&bo->list, &kgem->large_inactive);
1549
		return;
1549
		return;
1550
	}
1550
	}
1551
 
1551
 
1552
	assert(bo->flush == false);
1552
	assert(bo->flush == false);
1553
	list_move(&bo->list, &kgem->inactive[bucket(bo)]);
1553
	list_move(&bo->list, &kgem->inactive[bucket(bo)]);
1554
	if (bo->map) {
1554
	if (bo->map) {
1555
		int type = IS_CPU_MAP(bo->map);
1555
		int type = IS_CPU_MAP(bo->map);
1556
		if (bucket(bo) >= NUM_CACHE_BUCKETS ||
1556
		if (bucket(bo) >= NUM_CACHE_BUCKETS ||
1557
		    (!type && !__kgem_bo_is_mappable(kgem, bo))) {
1557
		    (!type && !__kgem_bo_is_mappable(kgem, bo))) {
1558
//			munmap(MAP(bo->map), bytes(bo));
1558
//			munmap(MAP(bo->map), bytes(bo));
1559
			bo->map = NULL;
1559
			bo->map = NULL;
1560
		}
1560
		}
1561
		if (bo->map) {
1561
		if (bo->map) {
1562
			list_add(&bo->vma, &kgem->vma[type].inactive[bucket(bo)]);
1562
			list_add(&bo->vma, &kgem->vma[type].inactive[bucket(bo)]);
1563
			kgem->vma[type].count++;
1563
			kgem->vma[type].count++;
1564
		}
1564
		}
1565
	}
1565
	}
1566
}
1566
}
1567
 
1567
 
1568
static struct kgem_bo *kgem_bo_replace_io(struct kgem_bo *bo)
1568
static struct kgem_bo *kgem_bo_replace_io(struct kgem_bo *bo)
1569
{
1569
{
1570
	struct kgem_bo *base;
1570
	struct kgem_bo *base;
1571
 
1571
 
1572
	if (!bo->io)
1572
	if (!bo->io)
1573
		return bo;
1573
		return bo;
1574
 
1574
 
1575
	assert(!bo->snoop);
1575
	assert(!bo->snoop);
1576
	base = malloc(sizeof(*base));
1576
	base = malloc(sizeof(*base));
1577
	if (base) {
1577
	if (base) {
1578
		DBG(("%s: transferring io handle=%d to bo\n",
1578
		DBG(("%s: transferring io handle=%d to bo\n",
1579
		     __FUNCTION__, bo->handle));
1579
		     __FUNCTION__, bo->handle));
1580
		/* transfer the handle to a minimum bo */
1580
		/* transfer the handle to a minimum bo */
1581
		memcpy(base, bo, sizeof(*base));
1581
		memcpy(base, bo, sizeof(*base));
1582
		base->io = false;
1582
		base->io = false;
1583
		list_init(&base->list);
1583
		list_init(&base->list);
1584
		list_replace(&bo->request, &base->request);
1584
		list_replace(&bo->request, &base->request);
1585
		list_replace(&bo->vma, &base->vma);
1585
		list_replace(&bo->vma, &base->vma);
1586
		free(bo);
1586
		free(bo);
1587
		bo = base;
1587
		bo = base;
1588
	} else
1588
	} else
1589
		bo->reusable = false;
1589
		bo->reusable = false;
1590
 
1590
 
1591
	return bo;
1591
	return bo;
1592
}
1592
}
1593
 
1593
 
1594
inline static void kgem_bo_remove_from_inactive(struct kgem *kgem,
1594
inline static void kgem_bo_remove_from_inactive(struct kgem *kgem,
1595
						struct kgem_bo *bo)
1595
						struct kgem_bo *bo)
1596
{
1596
{
1597
	DBG(("%s: removing handle=%d from inactive\n", __FUNCTION__, bo->handle));
1597
	DBG(("%s: removing handle=%d from inactive\n", __FUNCTION__, bo->handle));
1598
 
1598
 
1599
	list_del(&bo->list);
1599
	list_del(&bo->list);
1600
	assert(bo->rq == NULL);
1600
	assert(bo->rq == NULL);
1601
	assert(bo->exec == NULL);
1601
	assert(bo->exec == NULL);
1602
	if (bo->map) {
1602
	if (bo->map) {
1603
		assert(!list_is_empty(&bo->vma));
1603
		assert(!list_is_empty(&bo->vma));
1604
		list_del(&bo->vma);
1604
		list_del(&bo->vma);
1605
		kgem->vma[IS_CPU_MAP(bo->map)].count--;
1605
		kgem->vma[IS_CPU_MAP(bo->map)].count--;
1606
	}
1606
	}
1607
}
1607
}
1608
 
1608
 
1609
inline static void kgem_bo_remove_from_active(struct kgem *kgem,
1609
inline static void kgem_bo_remove_from_active(struct kgem *kgem,
1610
					      struct kgem_bo *bo)
1610
					      struct kgem_bo *bo)
1611
{
1611
{
1612
	DBG(("%s: removing handle=%d from active\n", __FUNCTION__, bo->handle));
1612
	DBG(("%s: removing handle=%d from active\n", __FUNCTION__, bo->handle));
1613
 
1613
 
1614
	list_del(&bo->list);
1614
	list_del(&bo->list);
1615
	assert(bo->rq != NULL);
1615
	assert(bo->rq != NULL);
1616
	if (bo->rq == (void *)kgem)
1616
	if (bo->rq == (void *)kgem)
1617
		list_del(&bo->request);
1617
		list_del(&bo->request);
1618
	assert(list_is_empty(&bo->vma));
1618
	assert(list_is_empty(&bo->vma));
1619
}
1619
}
1620
 
1620
 
1621
static void _kgem_bo_delete_buffer(struct kgem *kgem, struct kgem_bo *bo)
1621
static void _kgem_bo_delete_buffer(struct kgem *kgem, struct kgem_bo *bo)
1622
{
1622
{
1623
	struct kgem_buffer *io = (struct kgem_buffer *)bo->proxy;
1623
	struct kgem_buffer *io = (struct kgem_buffer *)bo->proxy;
1624
 
1624
 
1625
	DBG(("%s: size=%d, offset=%d, parent used=%d\n",
1625
	DBG(("%s: size=%d, offset=%d, parent used=%d\n",
1626
	     __FUNCTION__, bo->size.bytes, bo->delta, io->used));
1626
	     __FUNCTION__, bo->size.bytes, bo->delta, io->used));
1627
 
1627
 
1628
	if (ALIGN(bo->delta + bo->size.bytes, UPLOAD_ALIGNMENT) == io->used)
1628
	if (ALIGN(bo->delta + bo->size.bytes, UPLOAD_ALIGNMENT) == io->used)
1629
		io->used = bo->delta;
1629
		io->used = bo->delta;
1630
}
1630
}
1631
 
1631
 
1632
static void kgem_bo_move_to_scanout(struct kgem *kgem, struct kgem_bo *bo)
1632
static void kgem_bo_move_to_scanout(struct kgem *kgem, struct kgem_bo *bo)
1633
{
1633
{
1634
	assert(bo->refcnt == 0);
1634
	assert(bo->refcnt == 0);
1635
	assert(bo->scanout);
1635
	assert(bo->scanout);
1636
	assert(bo->delta);
1636
	assert(bo->delta);
1637
	assert(!bo->flush);
1637
	assert(!bo->flush);
1638
	assert(!bo->snoop);
1638
	assert(!bo->snoop);
1639
	assert(!bo->io);
1639
	assert(!bo->io);
1640
 
1640
 
1641
	if (bo->purged) {
1641
	if (bo->purged) {
1642
		DBG(("%s: discarding purged scanout - external name?\n",
1642
		DBG(("%s: discarding purged scanout - external name?\n",
1643
		     __FUNCTION__));
1643
		     __FUNCTION__));
1644
		kgem_bo_free(kgem, bo);
1644
		kgem_bo_free(kgem, bo);
1645
		return;
1645
		return;
1646
	}
1646
	}
1647
 
1647
 
1648
	DBG(("%s: moving %d [fb %d] to scanout cache, active? %d\n",
1648
	DBG(("%s: moving %d [fb %d] to scanout cache, active? %d\n",
1649
	     __FUNCTION__, bo->handle, bo->delta, bo->rq != NULL));
1649
	     __FUNCTION__, bo->handle, bo->delta, bo->rq != NULL));
1650
	if (bo->rq)
1650
	if (bo->rq)
1651
		list_move_tail(&bo->list, &kgem->scanout);
1651
		list_move_tail(&bo->list, &kgem->scanout);
1652
	else
1652
	else
1653
	list_move(&bo->list, &kgem->scanout);
1653
	list_move(&bo->list, &kgem->scanout);
1654
}
1654
}
1655
 
1655
 
1656
static void kgem_bo_move_to_snoop(struct kgem *kgem, struct kgem_bo *bo)
1656
static void kgem_bo_move_to_snoop(struct kgem *kgem, struct kgem_bo *bo)
1657
{
1657
{
1658
	assert(bo->reusable);
1658
	assert(bo->reusable);
1659
	assert(!bo->flush);
1659
	assert(!bo->flush);
1660
	assert(!bo->needs_flush);
1660
	assert(!bo->needs_flush);
1661
	assert(bo->refcnt == 0);
1661
	assert(bo->refcnt == 0);
1662
	assert(bo->exec == NULL);
1662
	assert(bo->exec == NULL);
1663
 
1663
 
1664
	if (num_pages(bo) > kgem->max_cpu_size >> 13) {
1664
	if (num_pages(bo) > kgem->max_cpu_size >> 13) {
1665
		DBG(("%s handle=%d discarding large CPU buffer (%d >%d pages)\n",
1665
		DBG(("%s handle=%d discarding large CPU buffer (%d >%d pages)\n",
1666
		     __FUNCTION__, bo->handle, num_pages(bo), kgem->max_cpu_size >> 13));
1666
		     __FUNCTION__, bo->handle, num_pages(bo), kgem->max_cpu_size >> 13));
1667
		kgem_bo_free(kgem, bo);
1667
		kgem_bo_free(kgem, bo);
1668
		return;
1668
		return;
1669
	}
1669
	}
1670
 
1670
 
1671
	assert(bo->tiling == I915_TILING_NONE);
1671
	assert(bo->tiling == I915_TILING_NONE);
1672
	assert(bo->rq == NULL);
1672
	assert(bo->rq == NULL);
1673
 
1673
 
1674
	DBG(("%s: moving %d to snoop cachee\n", __FUNCTION__, bo->handle));
1674
	DBG(("%s: moving %d to snoop cachee\n", __FUNCTION__, bo->handle));
1675
	list_add(&bo->list, &kgem->snoop);
1675
	list_add(&bo->list, &kgem->snoop);
1676
}
1676
}
1677
 
1677
 
1678
static struct kgem_bo *
1678
static struct kgem_bo *
1679
search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags)
1679
search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags)
1680
{
1680
{
1681
	struct kgem_bo *bo, *first = NULL;
1681
	struct kgem_bo *bo, *first = NULL;
1682
 
1682
 
1683
	DBG(("%s: num_pages=%d, flags=%x\n", __FUNCTION__, num_pages, flags));
1683
	DBG(("%s: num_pages=%d, flags=%x\n", __FUNCTION__, num_pages, flags));
1684
 
1684
 
1685
	if ((kgem->has_caching | kgem->has_userptr) == 0)
1685
	if ((kgem->has_caching | kgem->has_userptr) == 0)
1686
		return NULL;
1686
		return NULL;
1687
 
1687
 
1688
	if (list_is_empty(&kgem->snoop)) {
1688
	if (list_is_empty(&kgem->snoop)) {
1689
		DBG(("%s: inactive and cache empty\n", __FUNCTION__));
1689
		DBG(("%s: inactive and cache empty\n", __FUNCTION__));
1690
		if (!__kgem_throttle_retire(kgem, flags)) {
1690
		if (!__kgem_throttle_retire(kgem, flags)) {
1691
			DBG(("%s: nothing retired\n", __FUNCTION__));
1691
			DBG(("%s: nothing retired\n", __FUNCTION__));
1692
			return NULL;
1692
			return NULL;
1693
		}
1693
		}
1694
	}
1694
	}
1695
 
1695
 
1696
	list_for_each_entry(bo, &kgem->snoop, list) {
1696
	list_for_each_entry(bo, &kgem->snoop, list) {
1697
		assert(bo->refcnt == 0);
1697
		assert(bo->refcnt == 0);
1698
		assert(bo->snoop);
1698
		assert(bo->snoop);
1699
		assert(!bo->scanout);
1699
		assert(!bo->scanout);
1700
		assert(!bo->purged);
1700
		assert(!bo->purged);
1701
		assert(bo->proxy == NULL);
1701
		assert(bo->proxy == NULL);
1702
		assert(bo->tiling == I915_TILING_NONE);
1702
		assert(bo->tiling == I915_TILING_NONE);
1703
		assert(bo->rq == NULL);
1703
		assert(bo->rq == NULL);
1704
		assert(bo->exec == NULL);
1704
		assert(bo->exec == NULL);
1705
 
1705
 
1706
		if (num_pages > num_pages(bo))
1706
		if (num_pages > num_pages(bo))
1707
			continue;
1707
			continue;
1708
 
1708
 
1709
		if (num_pages(bo) > 2*num_pages) {
1709
		if (num_pages(bo) > 2*num_pages) {
1710
			if (first == NULL)
1710
			if (first == NULL)
1711
				first = bo;
1711
				first = bo;
1712
			continue;
1712
			continue;
1713
		}
1713
		}
1714
 
1714
 
1715
		list_del(&bo->list);
1715
		list_del(&bo->list);
1716
		bo->pitch = 0;
1716
		bo->pitch = 0;
1717
		bo->delta = 0;
1717
		bo->delta = 0;
1718
 
1718
 
1719
		DBG(("  %s: found handle=%d (num_pages=%d) in snoop cache\n",
1719
		DBG(("  %s: found handle=%d (num_pages=%d) in snoop cache\n",
1720
		     __FUNCTION__, bo->handle, num_pages(bo)));
1720
		     __FUNCTION__, bo->handle, num_pages(bo)));
1721
		return bo;
1721
		return bo;
1722
	}
1722
	}
1723
 
1723
 
1724
	if (first) {
1724
	if (first) {
1725
		list_del(&first->list);
1725
		list_del(&first->list);
1726
		first->pitch = 0;
1726
		first->pitch = 0;
1727
		first->delta = 0;
1727
		first->delta = 0;
1728
 
1728
 
1729
		DBG(("  %s: found handle=%d (num_pages=%d) in snoop cache\n",
1729
		DBG(("  %s: found handle=%d (num_pages=%d) in snoop cache\n",
1730
		     __FUNCTION__, first->handle, num_pages(first)));
1730
		     __FUNCTION__, first->handle, num_pages(first)));
1731
		return first;
1731
		return first;
1732
	}
1732
	}
1733
 
1733
 
1734
	return NULL;
1734
	return NULL;
1735
}
1735
}
1736
 
1736
 
1737
void kgem_bo_undo(struct kgem *kgem, struct kgem_bo *bo)
1737
void kgem_bo_undo(struct kgem *kgem, struct kgem_bo *bo)
1738
{
1738
{
1739
	if (kgem->nexec != 1 || bo->exec == NULL)
1739
	if (kgem->nexec != 1 || bo->exec == NULL)
1740
		return;
1740
		return;
1741
 
1741
 
1742
	DBG(("%s: only handle in batch, discarding last operations for handle=%d\n",
1742
	DBG(("%s: only handle in batch, discarding last operations for handle=%d\n",
1743
	     __FUNCTION__, bo->handle));
1743
	     __FUNCTION__, bo->handle));
1744
 
1744
 
1745
	assert(bo->exec == &kgem->exec[0]);
1745
	assert(bo->exec == &kgem->exec[0]);
1746
	assert(kgem->exec[0].handle == bo->handle);
1746
	assert(kgem->exec[0].handle == bo->handle);
1747
	assert(RQ(bo->rq) == kgem->next_request);
1747
	assert(RQ(bo->rq) == kgem->next_request);
1748
 
1748
 
1749
	bo->refcnt++;
1749
	bo->refcnt++;
1750
	kgem_reset(kgem);
1750
	kgem_reset(kgem);
1751
	bo->refcnt--;
1751
	bo->refcnt--;
1752
}
1752
}
1753
 
1753
 
1754
static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
1754
static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
1755
{
1755
{
1756
	DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
1756
	DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
1757
 
1757
 
1758
	assert(list_is_empty(&bo->list));
1758
	assert(list_is_empty(&bo->list));
1759
	assert(bo->refcnt == 0);
1759
	assert(bo->refcnt == 0);
1760
	assert(!bo->purged || !bo->reusable);
1760
	assert(!bo->purged || !bo->reusable);
1761
	assert(bo->proxy == NULL);
1761
	assert(bo->proxy == NULL);
1762
	assert_tiling(kgem, bo);
1762
	assert_tiling(kgem, bo);
1763
 
1763
 
1764
	bo->binding.offset = 0;
1764
	bo->binding.offset = 0;
1765
 
1765
 
1766
	if (DBG_NO_CACHE)
1766
	if (DBG_NO_CACHE)
1767
		goto destroy;
1767
		goto destroy;
1768
 
1768
 
1769
	if (bo->snoop && !bo->flush) {
1769
	if (bo->snoop && !bo->flush) {
1770
		DBG(("%s: handle=%d is snooped\n", __FUNCTION__, bo->handle));
1770
		DBG(("%s: handle=%d is snooped\n", __FUNCTION__, bo->handle));
1771
		assert(bo->reusable);
1771
		assert(bo->reusable);
1772
		assert(list_is_empty(&bo->list));
1772
		assert(list_is_empty(&bo->list));
1773
		if (bo->exec == NULL && bo->rq && !__kgem_busy(kgem, bo->handle))
1773
		if (bo->exec == NULL && bo->rq && !__kgem_busy(kgem, bo->handle))
1774
			__kgem_bo_clear_busy(bo);
1774
			__kgem_bo_clear_busy(bo);
1775
		if (bo->rq == NULL)
1775
		if (bo->rq == NULL)
1776
			kgem_bo_move_to_snoop(kgem, bo);
1776
			kgem_bo_move_to_snoop(kgem, bo);
1777
		return;
1777
		return;
1778
	}
1778
	}
1779
	if (!IS_USER_MAP(bo->map))
1779
	if (!IS_USER_MAP(bo->map))
1780
		bo->flush = false;
1780
		bo->flush = false;
1781
 
1781
 
1782
	if (bo->scanout) {
1782
	if (bo->scanout) {
1783
		kgem_bo_move_to_scanout(kgem, bo);
1783
		kgem_bo_move_to_scanout(kgem, bo);
1784
		return;
1784
		return;
1785
	}
1785
	}
1786
 
1786
 
1787
	if (bo->io)
1787
	if (bo->io)
1788
		bo = kgem_bo_replace_io(bo);
1788
		bo = kgem_bo_replace_io(bo);
1789
	if (!bo->reusable) {
1789
	if (!bo->reusable) {
1790
		DBG(("%s: handle=%d, not reusable\n",
1790
		DBG(("%s: handle=%d, not reusable\n",
1791
		     __FUNCTION__, bo->handle));
1791
		     __FUNCTION__, bo->handle));
1792
		goto destroy;
1792
		goto destroy;
1793
	}
1793
	}
1794
 
1794
 
1795
	if (!kgem->has_llc && IS_CPU_MAP(bo->map) && bo->domain != DOMAIN_CPU)
1795
	if (!kgem->has_llc && IS_CPU_MAP(bo->map) && bo->domain != DOMAIN_CPU)
1796
		kgem_bo_release_map(kgem, bo);
1796
		kgem_bo_release_map(kgem, bo);
1797
 
1797
 
1798
	assert(list_is_empty(&bo->vma));
1798
	assert(list_is_empty(&bo->vma));
1799
	assert(list_is_empty(&bo->list));
1799
	assert(list_is_empty(&bo->list));
1800
	assert(bo->flush == false);
1800
	assert(bo->flush == false);
1801
	assert(bo->snoop == false);
1801
	assert(bo->snoop == false);
1802
	assert(bo->io == false);
1802
	assert(bo->io == false);
1803
	assert(bo->scanout == false);
1803
	assert(bo->scanout == false);
1804
 
1804
 
1805
	kgem_bo_undo(kgem, bo);
1805
	kgem_bo_undo(kgem, bo);
1806
	assert(bo->refcnt == 0);
1806
	assert(bo->refcnt == 0);
1807
 
1807
 
1808
	if (bo->rq && bo->exec == NULL && !__kgem_busy(kgem, bo->handle))
1808
	if (bo->rq && bo->exec == NULL && !__kgem_busy(kgem, bo->handle))
1809
		__kgem_bo_clear_busy(bo);
1809
		__kgem_bo_clear_busy(bo);
1810
 
1810
 
1811
	if (bo->rq) {
1811
	if (bo->rq) {
1812
		struct list *cache;
1812
		struct list *cache;
1813
 
1813
 
1814
		DBG(("%s: handle=%d -> active\n", __FUNCTION__, bo->handle));
1814
		DBG(("%s: handle=%d -> active\n", __FUNCTION__, bo->handle));
1815
		if (bucket(bo) < NUM_CACHE_BUCKETS)
1815
		if (bucket(bo) < NUM_CACHE_BUCKETS)
1816
			cache = &kgem->active[bucket(bo)][bo->tiling];
1816
			cache = &kgem->active[bucket(bo)][bo->tiling];
1817
		else
1817
		else
1818
			cache = &kgem->large;
1818
			cache = &kgem->large;
1819
		list_add(&bo->list, cache);
1819
		list_add(&bo->list, cache);
1820
		return;
1820
		return;
1821
	}
1821
	}
1822
 
1822
 
1823
	assert(bo->exec == NULL);
1823
	assert(bo->exec == NULL);
1824
	assert(list_is_empty(&bo->request));
1824
	assert(list_is_empty(&bo->request));
1825
 
1825
 
1826
	if (!IS_CPU_MAP(bo->map)) {
1826
	if (!IS_CPU_MAP(bo->map)) {
1827
		if (!kgem_bo_set_purgeable(kgem, bo))
1827
		if (!kgem_bo_set_purgeable(kgem, bo))
1828
			goto destroy;
1828
			goto destroy;
1829
 
1829
 
1830
		if (!kgem->has_llc && bo->domain == DOMAIN_CPU)
1830
		if (!kgem->has_llc && bo->domain == DOMAIN_CPU)
1831
			goto destroy;
1831
			goto destroy;
1832
 
1832
 
1833
		DBG(("%s: handle=%d, purged\n",
1833
		DBG(("%s: handle=%d, purged\n",
1834
		     __FUNCTION__, bo->handle));
1834
		     __FUNCTION__, bo->handle));
1835
	}
1835
	}
1836
 
1836
 
1837
	kgem_bo_move_to_inactive(kgem, bo);
1837
	kgem_bo_move_to_inactive(kgem, bo);
1838
	return;
1838
	return;
1839
 
1839
 
1840
destroy:
1840
destroy:
1841
	if (!bo->exec)
1841
	if (!bo->exec)
1842
		kgem_bo_free(kgem, bo);
1842
		kgem_bo_free(kgem, bo);
1843
}
1843
}
1844
 
1844
 
1845
static void kgem_bo_unref(struct kgem *kgem, struct kgem_bo *bo)
1845
static void kgem_bo_unref(struct kgem *kgem, struct kgem_bo *bo)
1846
{
1846
{
1847
	assert(bo->refcnt);
1847
	assert(bo->refcnt);
1848
	if (--bo->refcnt == 0)
1848
	if (--bo->refcnt == 0)
1849
		__kgem_bo_destroy(kgem, bo);
1849
		__kgem_bo_destroy(kgem, bo);
1850
}
1850
}
1851
 
1851
 
1852
static void kgem_buffer_release(struct kgem *kgem, struct kgem_buffer *bo)
1852
static void kgem_buffer_release(struct kgem *kgem, struct kgem_buffer *bo)
1853
{
1853
{
1854
	while (!list_is_empty(&bo->base.vma)) {
1854
	while (!list_is_empty(&bo->base.vma)) {
1855
		struct kgem_bo *cached;
1855
		struct kgem_bo *cached;
1856
 
1856
 
1857
		cached = list_first_entry(&bo->base.vma, struct kgem_bo, vma);
1857
		cached = list_first_entry(&bo->base.vma, struct kgem_bo, vma);
1858
		assert(cached->proxy == &bo->base);
1858
		assert(cached->proxy == &bo->base);
1859
		list_del(&cached->vma);
1859
		list_del(&cached->vma);
1860
 
1860
 
1861
		assert(*(struct kgem_bo **)cached->map == cached);
1861
		assert(*(struct kgem_bo **)cached->map == cached);
1862
		*(struct kgem_bo **)cached->map = NULL;
1862
		*(struct kgem_bo **)cached->map = NULL;
1863
		cached->map = NULL;
1863
		cached->map = NULL;
1864
 
1864
 
1865
		kgem_bo_destroy(kgem, cached);
1865
		kgem_bo_destroy(kgem, cached);
1866
	}
1866
	}
1867
}
1867
}
1868
 
1868
 
1869
static bool kgem_retire__buffers(struct kgem *kgem)
1869
static bool kgem_retire__buffers(struct kgem *kgem)
1870
{
1870
{
1871
	bool retired = false;
1871
	bool retired = false;
1872
 
1872
 
1873
	while (!list_is_empty(&kgem->active_buffers)) {
1873
	while (!list_is_empty(&kgem->active_buffers)) {
1874
		struct kgem_buffer *bo =
1874
		struct kgem_buffer *bo =
1875
			list_last_entry(&kgem->active_buffers,
1875
			list_last_entry(&kgem->active_buffers,
1876
					struct kgem_buffer,
1876
					struct kgem_buffer,
1877
					base.list);
1877
					base.list);
1878
 
1878
 
1879
		if (bo->base.rq)
1879
		if (bo->base.rq)
1880
			break;
1880
			break;
1881
 
1881
 
1882
		DBG(("%s: releasing upload cache for handle=%d? %d\n",
1882
		DBG(("%s: releasing upload cache for handle=%d? %d\n",
1883
		     __FUNCTION__, bo->base.handle, !list_is_empty(&bo->base.vma)));
1883
		     __FUNCTION__, bo->base.handle, !list_is_empty(&bo->base.vma)));
1884
		list_del(&bo->base.list);
1884
		list_del(&bo->base.list);
1885
		kgem_buffer_release(kgem, bo);
1885
		kgem_buffer_release(kgem, bo);
1886
		kgem_bo_unref(kgem, &bo->base);
1886
		kgem_bo_unref(kgem, &bo->base);
1887
		retired = true;
1887
		retired = true;
1888
	}
1888
	}
1889
 
1889
 
1890
	return retired;
1890
	return retired;
1891
}
1891
}
1892
 
1892
 
1893
static bool kgem_retire__flushing(struct kgem *kgem)
1893
static bool kgem_retire__flushing(struct kgem *kgem)
1894
{
1894
{
1895
	struct kgem_bo *bo, *next;
1895
	struct kgem_bo *bo, *next;
1896
	bool retired = false;
1896
	bool retired = false;
1897
 
1897
 
1898
	list_for_each_entry_safe(bo, next, &kgem->flushing, request) {
1898
	list_for_each_entry_safe(bo, next, &kgem->flushing, request) {
1899
		assert(bo->rq == (void *)kgem);
1899
		assert(bo->rq == (void *)kgem);
1900
		assert(bo->exec == NULL);
1900
		assert(bo->exec == NULL);
1901
 
1901
 
1902
		if (__kgem_busy(kgem, bo->handle))
1902
		if (__kgem_busy(kgem, bo->handle))
1903
			break;
1903
			break;
1904
 
1904
 
1905
		__kgem_bo_clear_busy(bo);
1905
		__kgem_bo_clear_busy(bo);
1906
 
1906
 
1907
		if (bo->refcnt)
1907
		if (bo->refcnt)
1908
			continue;
1908
			continue;
1909
 
1909
 
1910
		if (bo->snoop) {
1910
		if (bo->snoop) {
1911
			kgem_bo_move_to_snoop(kgem, bo);
1911
			kgem_bo_move_to_snoop(kgem, bo);
1912
		} else if (bo->scanout) {
1912
		} else if (bo->scanout) {
1913
			kgem_bo_move_to_scanout(kgem, bo);
1913
			kgem_bo_move_to_scanout(kgem, bo);
1914
		} else if ((bo = kgem_bo_replace_io(bo))->reusable &&
1914
		} else if ((bo = kgem_bo_replace_io(bo))->reusable &&
1915
			   kgem_bo_set_purgeable(kgem, bo)) {
1915
			   kgem_bo_set_purgeable(kgem, bo)) {
1916
			kgem_bo_move_to_inactive(kgem, bo);
1916
			kgem_bo_move_to_inactive(kgem, bo);
1917
			retired = true;
1917
			retired = true;
1918
		} else
1918
		} else
1919
			kgem_bo_free(kgem, bo);
1919
			kgem_bo_free(kgem, bo);
1920
	}
1920
	}
1921
#if HAS_DEBUG_FULL
1921
#if HAS_DEBUG_FULL
1922
	{
1922
	{
1923
		int count = 0;
1923
		int count = 0;
1924
		list_for_each_entry(bo, &kgem->flushing, request)
1924
		list_for_each_entry(bo, &kgem->flushing, request)
1925
			count++;
1925
			count++;
1926
		ErrorF("%s: %d bo on flushing list\n", __FUNCTION__, count);
1926
		ErrorF("%s: %d bo on flushing list\n", __FUNCTION__, count);
1927
	}
1927
	}
1928
#endif
1928
#endif
1929
 
1929
 
1930
	kgem->need_retire |= !list_is_empty(&kgem->flushing);
1930
	kgem->need_retire |= !list_is_empty(&kgem->flushing);
1931
 
1931
 
1932
	return retired;
1932
	return retired;
1933
}
1933
}
1934
 
1934
 
1935
 
1935
 
1936
static bool __kgem_retire_rq(struct kgem *kgem, struct kgem_request *rq)
1936
static bool __kgem_retire_rq(struct kgem *kgem, struct kgem_request *rq)
1937
{
1937
{
1938
	bool retired = false;
1938
	bool retired = false;
1939
 
1939
 
1940
	DBG(("%s: request %d complete\n",
1940
	DBG(("%s: request %d complete\n",
1941
	     __FUNCTION__, rq->bo->handle));
1941
	     __FUNCTION__, rq->bo->handle));
1942
 
1942
 
1943
	while (!list_is_empty(&rq->buffers)) {
1943
	while (!list_is_empty(&rq->buffers)) {
1944
		struct kgem_bo *bo;
1944
		struct kgem_bo *bo;
1945
 
1945
 
1946
		bo = list_first_entry(&rq->buffers,
1946
		bo = list_first_entry(&rq->buffers,
1947
				      struct kgem_bo,
1947
				      struct kgem_bo,
1948
				      request);
1948
				      request);
1949
 
1949
 
1950
		assert(RQ(bo->rq) == rq);
1950
		assert(RQ(bo->rq) == rq);
1951
		assert(bo->exec == NULL);
1951
		assert(bo->exec == NULL);
1952
		assert(bo->domain == DOMAIN_GPU || bo->domain == DOMAIN_NONE);
1952
		assert(bo->domain == DOMAIN_GPU || bo->domain == DOMAIN_NONE);
1953
 
1953
 
1954
		list_del(&bo->request);
1954
		list_del(&bo->request);
1955
 
1955
 
1956
		if (bo->needs_flush)
1956
		if (bo->needs_flush)
1957
			bo->needs_flush = __kgem_busy(kgem, bo->handle);
1957
			bo->needs_flush = __kgem_busy(kgem, bo->handle);
1958
		if (bo->needs_flush) {
1958
		if (bo->needs_flush) {
1959
			DBG(("%s: moving %d to flushing\n",
1959
			DBG(("%s: moving %d to flushing\n",
1960
			     __FUNCTION__, bo->handle));
1960
			     __FUNCTION__, bo->handle));
1961
			list_add(&bo->request, &kgem->flushing);
1961
			list_add(&bo->request, &kgem->flushing);
1962
			bo->rq = (void *)kgem;
1962
			bo->rq = (void *)kgem;
1963
			continue;
1963
			continue;
1964
		}
1964
		}
1965
 
1965
 
1966
		bo->domain = DOMAIN_NONE;
1966
		bo->domain = DOMAIN_NONE;
1967
		bo->rq = NULL;
1967
		bo->rq = NULL;
1968
		if (bo->refcnt)
1968
		if (bo->refcnt)
1969
			continue;
1969
			continue;
1970
 
1970
 
1971
		if (bo->snoop) {
1971
		if (bo->snoop) {
1972
			kgem_bo_move_to_snoop(kgem, bo);
1972
			kgem_bo_move_to_snoop(kgem, bo);
1973
		} else if (bo->scanout) {
1973
		} else if (bo->scanout) {
1974
			kgem_bo_move_to_scanout(kgem, bo);
1974
			kgem_bo_move_to_scanout(kgem, bo);
1975
		} else if ((bo = kgem_bo_replace_io(bo))->reusable &&
1975
		} else if ((bo = kgem_bo_replace_io(bo))->reusable &&
1976
			   kgem_bo_set_purgeable(kgem, bo)) {
1976
			   kgem_bo_set_purgeable(kgem, bo)) {
1977
			kgem_bo_move_to_inactive(kgem, bo);
1977
			kgem_bo_move_to_inactive(kgem, bo);
1978
			retired = true;
1978
			retired = true;
1979
		} else {
1979
		} else {
1980
			DBG(("%s: closing %d\n",
1980
			DBG(("%s: closing %d\n",
1981
			     __FUNCTION__, bo->handle));
1981
			     __FUNCTION__, bo->handle));
1982
			kgem_bo_free(kgem, bo);
1982
			kgem_bo_free(kgem, bo);
1983
		}
1983
		}
1984
	}
1984
	}
1985
 
1985
 
1986
	assert(rq->bo->rq == NULL);
1986
	assert(rq->bo->rq == NULL);
1987
	assert(list_is_empty(&rq->bo->request));
1987
	assert(list_is_empty(&rq->bo->request));
1988
 
1988
 
1989
	if (--rq->bo->refcnt == 0) {
1989
	if (--rq->bo->refcnt == 0) {
1990
		if (kgem_bo_set_purgeable(kgem, rq->bo)) {
1990
		if (kgem_bo_set_purgeable(kgem, rq->bo)) {
1991
			kgem_bo_move_to_inactive(kgem, rq->bo);
1991
			kgem_bo_move_to_inactive(kgem, rq->bo);
1992
			retired = true;
1992
			retired = true;
1993
		} else {
1993
		} else {
1994
			DBG(("%s: closing %d\n",
1994
			DBG(("%s: closing %d\n",
1995
			     __FUNCTION__, rq->bo->handle));
1995
			     __FUNCTION__, rq->bo->handle));
1996
			kgem_bo_free(kgem, rq->bo);
1996
			kgem_bo_free(kgem, rq->bo);
1997
		}
1997
		}
1998
	}
1998
	}
1999
 
1999
 
2000
	__kgem_request_free(rq);
2000
	__kgem_request_free(rq);
2001
	return retired;
2001
	return retired;
2002
}
2002
}
2003
 
2003
 
2004
static bool kgem_retire__requests_ring(struct kgem *kgem, int ring)
2004
static bool kgem_retire__requests_ring(struct kgem *kgem, int ring)
2005
{
2005
{
2006
	bool retired = false;
2006
	bool retired = false;
2007
 
2007
 
2008
	while (!list_is_empty(&kgem->requests[ring])) {
2008
	while (!list_is_empty(&kgem->requests[ring])) {
2009
		struct kgem_request *rq;
2009
		struct kgem_request *rq;
2010
 
2010
 
2011
		rq = list_first_entry(&kgem->requests[ring],
2011
		rq = list_first_entry(&kgem->requests[ring],
2012
				      struct kgem_request,
2012
				      struct kgem_request,
2013
				      list);
2013
				      list);
2014
		if (__kgem_busy(kgem, rq->bo->handle))
2014
		if (__kgem_busy(kgem, rq->bo->handle))
2015
			break;
2015
			break;
2016
 
2016
 
2017
		retired |= __kgem_retire_rq(kgem, rq);
2017
		retired |= __kgem_retire_rq(kgem, rq);
2018
	}
2018
	}
2019
 
2019
 
2020
#if HAS_DEBUG_FULL
2020
#if HAS_DEBUG_FULL
2021
	{
2021
	{
2022
		struct kgem_bo *bo;
2022
		struct kgem_bo *bo;
2023
		int count = 0;
2023
		int count = 0;
2024
 
2024
 
2025
		list_for_each_entry(bo, &kgem->requests[ring], request)
2025
		list_for_each_entry(bo, &kgem->requests[ring], request)
2026
			count++;
2026
			count++;
2027
 
2027
 
2028
		bo = NULL;
2028
		bo = NULL;
2029
		if (!list_is_empty(&kgem->requests[ring]))
2029
		if (!list_is_empty(&kgem->requests[ring]))
2030
			bo = list_first_entry(&kgem->requests[ring],
2030
			bo = list_first_entry(&kgem->requests[ring],
2031
					      struct kgem_request,
2031
					      struct kgem_request,
2032
					      list)->bo;
2032
					      list)->bo;
2033
 
2033
 
2034
		ErrorF("%s: ring=%d, %d outstanding requests, oldest=%d\n",
2034
		ErrorF("%s: ring=%d, %d outstanding requests, oldest=%d\n",
2035
		       __FUNCTION__, ring, count, bo ? bo->handle : 0);
2035
		       __FUNCTION__, ring, count, bo ? bo->handle : 0);
2036
	}
2036
	}
2037
#endif
2037
#endif
2038
 
2038
 
2039
	return retired;
2039
	return retired;
2040
}
2040
}
2041
 
2041
 
2042
static bool kgem_retire__requests(struct kgem *kgem)
2042
static bool kgem_retire__requests(struct kgem *kgem)
2043
{
2043
{
2044
	bool retired = false;
2044
	bool retired = false;
2045
	int n;
2045
	int n;
2046
 
2046
 
2047
	for (n = 0; n < ARRAY_SIZE(kgem->requests); n++) {
2047
	for (n = 0; n < ARRAY_SIZE(kgem->requests); n++) {
2048
		retired |= kgem_retire__requests_ring(kgem, n);
2048
		retired |= kgem_retire__requests_ring(kgem, n);
2049
		kgem->need_retire |= !list_is_empty(&kgem->requests[n]);
2049
		kgem->need_retire |= !list_is_empty(&kgem->requests[n]);
2050
	}
2050
	}
2051
 
2051
 
2052
	return retired;
2052
	return retired;
2053
}
2053
}
2054
 
2054
 
2055
bool kgem_retire(struct kgem *kgem)
2055
bool kgem_retire(struct kgem *kgem)
2056
{
2056
{
2057
	bool retired = false;
2057
	bool retired = false;
2058
 
2058
 
2059
	DBG(("%s\n", __FUNCTION__));
2059
	DBG(("%s\n", __FUNCTION__));
2060
 
2060
 
2061
	kgem->need_retire = false;
2061
	kgem->need_retire = false;
2062
 
2062
 
2063
	retired |= kgem_retire__flushing(kgem);
2063
	retired |= kgem_retire__flushing(kgem);
2064
	retired |= kgem_retire__requests(kgem);
2064
	retired |= kgem_retire__requests(kgem);
2065
	retired |= kgem_retire__buffers(kgem);
2065
	retired |= kgem_retire__buffers(kgem);
2066
 
2066
 
2067
	DBG(("%s -- retired=%d, need_retire=%d\n",
2067
	DBG(("%s -- retired=%d, need_retire=%d\n",
2068
	     __FUNCTION__, retired, kgem->need_retire));
2068
	     __FUNCTION__, retired, kgem->need_retire));
2069
 
2069
 
2070
	kgem->retire(kgem);
2070
	kgem->retire(kgem);
2071
 
2071
 
2072
	return retired;
2072
	return retired;
2073
}
2073
}
2074
 
2074
 
2075
bool __kgem_ring_is_idle(struct kgem *kgem, int ring)
2075
bool __kgem_ring_is_idle(struct kgem *kgem, int ring)
2076
{
2076
{
2077
	struct kgem_request *rq;
2077
	struct kgem_request *rq;
2078
 
2078
 
2079
	assert(!list_is_empty(&kgem->requests[ring]));
2079
	assert(!list_is_empty(&kgem->requests[ring]));
2080
 
2080
 
2081
	rq = list_last_entry(&kgem->requests[ring],
2081
	rq = list_last_entry(&kgem->requests[ring],
2082
			     struct kgem_request, list);
2082
			     struct kgem_request, list);
2083
	if (__kgem_busy(kgem, rq->bo->handle)) {
2083
	if (__kgem_busy(kgem, rq->bo->handle)) {
2084
		DBG(("%s: last requests handle=%d still busy\n",
2084
		DBG(("%s: last requests handle=%d still busy\n",
2085
		     __FUNCTION__, rq->bo->handle));
2085
		     __FUNCTION__, rq->bo->handle));
2086
		return false;
2086
		return false;
2087
	}
2087
	}
2088
 
2088
 
2089
	DBG(("%s: ring=%d idle (handle=%d)\n",
2089
	DBG(("%s: ring=%d idle (handle=%d)\n",
2090
	     __FUNCTION__, ring, rq->bo->handle));
2090
	     __FUNCTION__, ring, rq->bo->handle));
2091
 
2091
 
2092
	kgem_retire__requests_ring(kgem, ring);
2092
	kgem_retire__requests_ring(kgem, ring);
2093
	assert(list_is_empty(&kgem->requests[ring]));
2093
	assert(list_is_empty(&kgem->requests[ring]));
2094
	return true;
2094
	return true;
2095
}
2095
}
2096
 
2096
 
2097
static void kgem_commit(struct kgem *kgem)
2097
static void kgem_commit(struct kgem *kgem)
2098
{
2098
{
2099
	struct kgem_request *rq = kgem->next_request;
2099
	struct kgem_request *rq = kgem->next_request;
2100
	struct kgem_bo *bo, *next;
2100
	struct kgem_bo *bo, *next;
2101
 
2101
 
2102
	list_for_each_entry_safe(bo, next, &rq->buffers, request) {
2102
	list_for_each_entry_safe(bo, next, &rq->buffers, request) {
2103
		assert(next->request.prev == &bo->request);
2103
		assert(next->request.prev == &bo->request);
2104
 
2104
 
2105
		DBG(("%s: release handle=%d (proxy? %d), dirty? %d flush? %d, snoop? %d -> offset=%x\n",
2105
		DBG(("%s: release handle=%d (proxy? %d), dirty? %d flush? %d, snoop? %d -> offset=%x\n",
2106
		     __FUNCTION__, bo->handle, bo->proxy != NULL,
2106
		     __FUNCTION__, bo->handle, bo->proxy != NULL,
2107
		     bo->gpu_dirty, bo->needs_flush, bo->snoop,
2107
		     bo->gpu_dirty, bo->needs_flush, bo->snoop,
2108
		     (unsigned)bo->exec->offset));
2108
		     (unsigned)bo->exec->offset));
2109
 
2109
 
2110
		assert(bo->exec);
2110
		assert(bo->exec);
2111
		assert(bo->proxy == NULL || bo->exec == &_kgem_dummy_exec);
2111
		assert(bo->proxy == NULL || bo->exec == &_kgem_dummy_exec);
2112
		assert(RQ(bo->rq) == rq || (RQ(bo->proxy->rq) == rq));
2112
		assert(RQ(bo->rq) == rq || (RQ(bo->proxy->rq) == rq));
2113
 
2113
 
2114
		bo->presumed_offset = bo->exec->offset;
2114
		bo->presumed_offset = bo->exec->offset;
2115
		bo->exec = NULL;
2115
		bo->exec = NULL;
2116
		bo->target_handle = -1;
2116
		bo->target_handle = -1;
2117
 
2117
 
2118
		if (!bo->refcnt && !bo->reusable) {
2118
		if (!bo->refcnt && !bo->reusable) {
2119
			assert(!bo->snoop);
2119
			assert(!bo->snoop);
2120
			kgem_bo_free(kgem, bo);
2120
			kgem_bo_free(kgem, bo);
2121
			continue;
2121
			continue;
2122
		}
2122
		}
2123
 
2123
 
2124
		bo->binding.offset = 0;
2124
		bo->binding.offset = 0;
2125
		bo->domain = DOMAIN_GPU;
2125
		bo->domain = DOMAIN_GPU;
2126
		bo->gpu_dirty = false;
2126
		bo->gpu_dirty = false;
2127
 
2127
 
2128
		if (bo->proxy) {
2128
		if (bo->proxy) {
2129
			/* proxies are not used for domain tracking */
2129
			/* proxies are not used for domain tracking */
2130
			bo->exec = NULL;
2130
			bo->exec = NULL;
2131
			__kgem_bo_clear_busy(bo);
2131
			__kgem_bo_clear_busy(bo);
2132
		}
2132
		}
2133
 
2133
 
2134
		kgem->scanout_busy |= bo->scanout;
2134
		kgem->scanout_busy |= bo->scanout;
2135
	}
2135
	}
2136
 
2136
 
2137
	if (rq == &kgem->static_request) {
2137
	if (rq == &kgem->static_request) {
2138
		struct drm_i915_gem_set_domain set_domain;
2138
		struct drm_i915_gem_set_domain set_domain;
2139
 
2139
 
2140
		DBG(("%s: syncing due to allocation failure\n", __FUNCTION__));
2140
		DBG(("%s: syncing due to allocation failure\n", __FUNCTION__));
2141
 
2141
 
2142
		VG_CLEAR(set_domain);
2142
		VG_CLEAR(set_domain);
2143
		set_domain.handle = rq->bo->handle;
2143
		set_domain.handle = rq->bo->handle;
2144
		set_domain.read_domains = I915_GEM_DOMAIN_GTT;
2144
		set_domain.read_domains = I915_GEM_DOMAIN_GTT;
2145
		set_domain.write_domain = I915_GEM_DOMAIN_GTT;
2145
		set_domain.write_domain = I915_GEM_DOMAIN_GTT;
2146
		if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
2146
		if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
2147
			DBG(("%s: sync: GPU hang detected\n", __FUNCTION__));
2147
			DBG(("%s: sync: GPU hang detected\n", __FUNCTION__));
2148
			kgem_throttle(kgem);
2148
			kgem_throttle(kgem);
2149
		}
2149
		}
2150
 
2150
 
2151
		kgem_retire(kgem);
2151
		kgem_retire(kgem);
2152
		assert(list_is_empty(&rq->buffers));
2152
		assert(list_is_empty(&rq->buffers));
2153
 
2153
 
2154
		assert(rq->bo->map == NULL);
2154
		assert(rq->bo->map == NULL);
2155
		gem_close(kgem->fd, rq->bo->handle);
2155
		gem_close(kgem->fd, rq->bo->handle);
2156
		kgem_cleanup_cache(kgem);
2156
		kgem_cleanup_cache(kgem);
2157
	} else {
2157
	} else {
2158
		list_add_tail(&rq->list, &kgem->requests[rq->ring]);
2158
		list_add_tail(&rq->list, &kgem->requests[rq->ring]);
2159
		kgem->need_throttle = kgem->need_retire = 1;
2159
		kgem->need_throttle = kgem->need_retire = 1;
2160
	}
2160
	}
2161
 
2161
 
2162
	kgem->next_request = NULL;
2162
	kgem->next_request = NULL;
2163
}
2163
}
2164
 
2164
 
2165
static void kgem_close_list(struct kgem *kgem, struct list *head)
2165
static void kgem_close_list(struct kgem *kgem, struct list *head)
2166
{
2166
{
2167
	while (!list_is_empty(head))
2167
	while (!list_is_empty(head))
2168
		kgem_bo_free(kgem, list_first_entry(head, struct kgem_bo, list));
2168
		kgem_bo_free(kgem, list_first_entry(head, struct kgem_bo, list));
2169
}
2169
}
2170
 
2170
 
2171
static void kgem_close_inactive(struct kgem *kgem)
2171
static void kgem_close_inactive(struct kgem *kgem)
2172
{
2172
{
2173
	unsigned int i;
2173
	unsigned int i;
2174
 
2174
 
2175
	for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++)
2175
	for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++)
2176
		kgem_close_list(kgem, &kgem->inactive[i]);
2176
		kgem_close_list(kgem, &kgem->inactive[i]);
2177
}
2177
}
2178
 
2178
 
2179
static void kgem_finish_buffers(struct kgem *kgem)
2179
static void kgem_finish_buffers(struct kgem *kgem)
2180
{
2180
{
2181
	struct kgem_buffer *bo, *next;
2181
	struct kgem_buffer *bo, *next;
2182
 
2182
 
2183
	list_for_each_entry_safe(bo, next, &kgem->batch_buffers, base.list) {
2183
	list_for_each_entry_safe(bo, next, &kgem->batch_buffers, base.list) {
2184
		DBG(("%s: buffer handle=%d, used=%d, exec?=%d, write=%d, mmapped=%s\n",
2184
		DBG(("%s: buffer handle=%d, used=%d, exec?=%d, write=%d, mmapped=%s\n",
2185
		     __FUNCTION__, bo->base.handle, bo->used, bo->base.exec!=NULL,
2185
		     __FUNCTION__, bo->base.handle, bo->used, bo->base.exec!=NULL,
2186
		     bo->write, bo->mmapped ? IS_CPU_MAP(bo->base.map) ? "cpu" : "gtt" : "no"));
2186
		     bo->write, bo->mmapped ? IS_CPU_MAP(bo->base.map) ? "cpu" : "gtt" : "no"));
2187
 
2187
 
2188
		assert(next->base.list.prev == &bo->base.list);
2188
		assert(next->base.list.prev == &bo->base.list);
2189
		assert(bo->base.io);
2189
		assert(bo->base.io);
2190
		assert(bo->base.refcnt >= 1);
2190
		assert(bo->base.refcnt >= 1);
2191
 
2191
 
2192
		if (!bo->base.exec) {
2192
		if (!bo->base.exec) {
2193
			DBG(("%s: skipping unattached handle=%d, used=%d\n",
2193
			DBG(("%s: skipping unattached handle=%d, used=%d\n",
2194
			     __FUNCTION__, bo->base.handle, bo->used));
2194
			     __FUNCTION__, bo->base.handle, bo->used));
2195
			continue;
2195
			continue;
2196
		}
2196
		}
2197
 
2197
 
2198
		if (!bo->write) {
2198
		if (!bo->write) {
2199
			assert(bo->base.exec || bo->base.refcnt > 1);
2199
			assert(bo->base.exec || bo->base.refcnt > 1);
2200
			goto decouple;
2200
			goto decouple;
2201
		}
2201
		}
2202
 
2202
 
2203
		if (bo->mmapped) {
2203
		if (bo->mmapped) {
2204
			int used;
2204
			int used;
2205
 
2205
 
2206
			assert(!bo->need_io);
2206
			assert(!bo->need_io);
2207
 
2207
 
2208
			used = ALIGN(bo->used, PAGE_SIZE);
2208
			used = ALIGN(bo->used, PAGE_SIZE);
2209
			if (!DBG_NO_UPLOAD_ACTIVE &&
2209
			if (!DBG_NO_UPLOAD_ACTIVE &&
2210
			    used + PAGE_SIZE <= bytes(&bo->base) &&
2210
			    used + PAGE_SIZE <= bytes(&bo->base) &&
2211
			    (kgem->has_llc || !IS_CPU_MAP(bo->base.map) || bo->base.snoop)) {
2211
			    (kgem->has_llc || !IS_CPU_MAP(bo->base.map) || bo->base.snoop)) {
2212
				DBG(("%s: retaining upload buffer (%d/%d)\n",
2212
				DBG(("%s: retaining upload buffer (%d/%d)\n",
2213
				     __FUNCTION__, bo->used, bytes(&bo->base)));
2213
				     __FUNCTION__, bo->used, bytes(&bo->base)));
2214
				bo->used = used;
2214
				bo->used = used;
2215
				list_move(&bo->base.list,
2215
				list_move(&bo->base.list,
2216
					  &kgem->active_buffers);
2216
					  &kgem->active_buffers);
2217
				continue;
2217
				continue;
2218
			}
2218
			}
2219
			DBG(("%s: discarding mmapped buffer, used=%d, map type=%d\n",
2219
			DBG(("%s: discarding mmapped buffer, used=%d, map type=%d\n",
2220
			     __FUNCTION__, bo->used, (int)__MAP_TYPE(bo->base.map)));
2220
			     __FUNCTION__, bo->used, (int)__MAP_TYPE(bo->base.map)));
2221
			goto decouple;
2221
			goto decouple;
2222
		}
2222
		}
2223
 
2223
 
2224
		if (!bo->used) {
2224
		if (!bo->used) {
2225
			/* Unless we replace the handle in the execbuffer,
2225
			/* Unless we replace the handle in the execbuffer,
2226
			 * then this bo will become active. So decouple it
2226
			 * then this bo will become active. So decouple it
2227
			 * from the buffer list and track it in the normal
2227
			 * from the buffer list and track it in the normal
2228
			 * manner.
2228
			 * manner.
2229
			 */
2229
			 */
2230
			goto decouple;
2230
			goto decouple;
2231
		}
2231
		}
2232
 
2232
 
2233
		assert(bo->need_io);
2233
		assert(bo->need_io);
2234
		assert(bo->base.rq == MAKE_REQUEST(kgem->next_request, kgem->ring));
2234
		assert(bo->base.rq == MAKE_REQUEST(kgem->next_request, kgem->ring));
2235
		assert(bo->base.domain != DOMAIN_GPU);
2235
		assert(bo->base.domain != DOMAIN_GPU);
2236
 
2236
 
2237
		if (bo->base.refcnt == 1 &&
2237
		if (bo->base.refcnt == 1 &&
2238
		    bo->base.size.pages.count > 1 &&
2238
		    bo->base.size.pages.count > 1 &&
2239
		    bo->used < bytes(&bo->base) / 2) {
2239
		    bo->used < bytes(&bo->base) / 2) {
2240
			struct kgem_bo *shrink;
2240
			struct kgem_bo *shrink;
2241
			unsigned alloc = NUM_PAGES(bo->used);
2241
			unsigned alloc = NUM_PAGES(bo->used);
2242
 
2242
 
2243
			shrink = search_snoop_cache(kgem, alloc,
2243
			shrink = search_snoop_cache(kgem, alloc,
2244
						    CREATE_INACTIVE | CREATE_NO_RETIRE);
2244
						    CREATE_INACTIVE | CREATE_NO_RETIRE);
2245
			if (shrink) {
2245
			if (shrink) {
2246
				void *map;
2246
				void *map;
2247
				int n;
2247
				int n;
2248
 
2248
 
2249
				DBG(("%s: used=%d, shrinking %d to %d, handle %d to %d\n",
2249
				DBG(("%s: used=%d, shrinking %d to %d, handle %d to %d\n",
2250
				     __FUNCTION__,
2250
				     __FUNCTION__,
2251
				     bo->used, bytes(&bo->base), bytes(shrink),
2251
				     bo->used, bytes(&bo->base), bytes(shrink),
2252
				     bo->base.handle, shrink->handle));
2252
				     bo->base.handle, shrink->handle));
2253
 
2253
 
2254
				assert(bo->used <= bytes(shrink));
2254
				assert(bo->used <= bytes(shrink));
2255
				map = kgem_bo_map__cpu(kgem, shrink);
2255
				map = kgem_bo_map__cpu(kgem, shrink);
2256
				if (map) {
2256
				if (map) {
2257
					kgem_bo_sync__cpu(kgem, shrink);
2257
					kgem_bo_sync__cpu(kgem, shrink);
2258
					memcpy(map, bo->mem, bo->used);
2258
					memcpy(map, bo->mem, bo->used);
2259
 
2259
 
2260
					shrink->target_handle =
2260
					shrink->target_handle =
2261
						kgem->has_handle_lut ? bo->base.target_handle : shrink->handle;
2261
						kgem->has_handle_lut ? bo->base.target_handle : shrink->handle;
2262
					for (n = 0; n < kgem->nreloc; n++) {
2262
					for (n = 0; n < kgem->nreloc; n++) {
2263
						if (kgem->reloc[n].target_handle == bo->base.target_handle) {
2263
						if (kgem->reloc[n].target_handle == bo->base.target_handle) {
2264
							kgem->reloc[n].target_handle = shrink->target_handle;
2264
							kgem->reloc[n].target_handle = shrink->target_handle;
2265
							kgem->reloc[n].presumed_offset = shrink->presumed_offset;
2265
							kgem->reloc[n].presumed_offset = shrink->presumed_offset;
2266
							kgem->batch[kgem->reloc[n].offset/sizeof(kgem->batch[0])] =
2266
							kgem->batch[kgem->reloc[n].offset/sizeof(kgem->batch[0])] =
2267
								kgem->reloc[n].delta + shrink->presumed_offset;
2267
								kgem->reloc[n].delta + shrink->presumed_offset;
2268
						}
2268
						}
2269
					}
2269
					}
2270
 
2270
 
2271
					bo->base.exec->handle = shrink->handle;
2271
					bo->base.exec->handle = shrink->handle;
2272
					bo->base.exec->offset = shrink->presumed_offset;
2272
					bo->base.exec->offset = shrink->presumed_offset;
2273
					shrink->exec = bo->base.exec;
2273
					shrink->exec = bo->base.exec;
2274
					shrink->rq = bo->base.rq;
2274
					shrink->rq = bo->base.rq;
2275
					list_replace(&bo->base.request,
2275
					list_replace(&bo->base.request,
2276
						     &shrink->request);
2276
						     &shrink->request);
2277
					list_init(&bo->base.request);
2277
					list_init(&bo->base.request);
2278
					shrink->needs_flush = bo->base.gpu_dirty;
2278
					shrink->needs_flush = bo->base.gpu_dirty;
2279
 
2279
 
2280
					bo->base.exec = NULL;
2280
					bo->base.exec = NULL;
2281
					bo->base.rq = NULL;
2281
					bo->base.rq = NULL;
2282
					bo->base.gpu_dirty = false;
2282
					bo->base.gpu_dirty = false;
2283
					bo->base.needs_flush = false;
2283
					bo->base.needs_flush = false;
2284
					bo->used = 0;
2284
					bo->used = 0;
2285
 
2285
 
2286
					goto decouple;
2286
					goto decouple;
2287
				}
2287
				}
2288
 
2288
 
2289
				__kgem_bo_destroy(kgem, shrink);
2289
				__kgem_bo_destroy(kgem, shrink);
2290
			}
2290
			}
2291
 
2291
 
2292
			shrink = search_linear_cache(kgem, alloc,
2292
			shrink = search_linear_cache(kgem, alloc,
2293
						     CREATE_INACTIVE | CREATE_NO_RETIRE);
2293
						     CREATE_INACTIVE | CREATE_NO_RETIRE);
2294
			if (shrink) {
2294
			if (shrink) {
2295
				int n;
2295
				int n;
2296
 
2296
 
2297
				DBG(("%s: used=%d, shrinking %d to %d, handle %d to %d\n",
2297
				DBG(("%s: used=%d, shrinking %d to %d, handle %d to %d\n",
2298
				     __FUNCTION__,
2298
				     __FUNCTION__,
2299
				     bo->used, bytes(&bo->base), bytes(shrink),
2299
				     bo->used, bytes(&bo->base), bytes(shrink),
2300
				     bo->base.handle, shrink->handle));
2300
				     bo->base.handle, shrink->handle));
2301
 
2301
 
2302
				assert(bo->used <= bytes(shrink));
2302
				assert(bo->used <= bytes(shrink));
2303
				if (gem_write(kgem->fd, shrink->handle,
2303
				if (gem_write(kgem->fd, shrink->handle,
2304
					      0, bo->used, bo->mem) == 0) {
2304
					      0, bo->used, bo->mem) == 0) {
2305
					shrink->target_handle =
2305
					shrink->target_handle =
2306
						kgem->has_handle_lut ? bo->base.target_handle : shrink->handle;
2306
						kgem->has_handle_lut ? bo->base.target_handle : shrink->handle;
2307
					for (n = 0; n < kgem->nreloc; n++) {
2307
					for (n = 0; n < kgem->nreloc; n++) {
2308
						if (kgem->reloc[n].target_handle == bo->base.target_handle) {
2308
						if (kgem->reloc[n].target_handle == bo->base.target_handle) {
2309
							kgem->reloc[n].target_handle = shrink->target_handle;
2309
							kgem->reloc[n].target_handle = shrink->target_handle;
2310
							kgem->reloc[n].presumed_offset = shrink->presumed_offset;
2310
							kgem->reloc[n].presumed_offset = shrink->presumed_offset;
2311
							kgem->batch[kgem->reloc[n].offset/sizeof(kgem->batch[0])] =
2311
							kgem->batch[kgem->reloc[n].offset/sizeof(kgem->batch[0])] =
2312
								kgem->reloc[n].delta + shrink->presumed_offset;
2312
								kgem->reloc[n].delta + shrink->presumed_offset;
2313
						}
2313
						}
2314
					}
2314
					}
2315
 
2315
 
2316
					bo->base.exec->handle = shrink->handle;
2316
					bo->base.exec->handle = shrink->handle;
2317
					bo->base.exec->offset = shrink->presumed_offset;
2317
					bo->base.exec->offset = shrink->presumed_offset;
2318
					shrink->exec = bo->base.exec;
2318
					shrink->exec = bo->base.exec;
2319
					shrink->rq = bo->base.rq;
2319
					shrink->rq = bo->base.rq;
2320
					list_replace(&bo->base.request,
2320
					list_replace(&bo->base.request,
2321
						     &shrink->request);
2321
						     &shrink->request);
2322
					list_init(&bo->base.request);
2322
					list_init(&bo->base.request);
2323
					shrink->needs_flush = bo->base.gpu_dirty;
2323
					shrink->needs_flush = bo->base.gpu_dirty;
2324
 
2324
 
2325
					bo->base.exec = NULL;
2325
					bo->base.exec = NULL;
2326
					bo->base.rq = NULL;
2326
					bo->base.rq = NULL;
2327
					bo->base.gpu_dirty = false;
2327
					bo->base.gpu_dirty = false;
2328
					bo->base.needs_flush = false;
2328
					bo->base.needs_flush = false;
2329
					bo->used = 0;
2329
					bo->used = 0;
2330
 
2330
 
2331
					goto decouple;
2331
					goto decouple;
2332
				}
2332
				}
2333
 
2333
 
2334
				__kgem_bo_destroy(kgem, shrink);
2334
				__kgem_bo_destroy(kgem, shrink);
2335
			}
2335
			}
2336
		}
2336
		}
2337
 
2337
 
2338
		DBG(("%s: handle=%d, uploading %d/%d\n",
2338
		DBG(("%s: handle=%d, uploading %d/%d\n",
2339
		     __FUNCTION__, bo->base.handle, bo->used, bytes(&bo->base)));
2339
		     __FUNCTION__, bo->base.handle, bo->used, bytes(&bo->base)));
2340
		ASSERT_IDLE(kgem, bo->base.handle);
2340
		ASSERT_IDLE(kgem, bo->base.handle);
2341
		assert(bo->used <= bytes(&bo->base));
2341
		assert(bo->used <= bytes(&bo->base));
2342
		gem_write(kgem->fd, bo->base.handle,
2342
		gem_write(kgem->fd, bo->base.handle,
2343
			  0, bo->used, bo->mem);
2343
			  0, bo->used, bo->mem);
2344
		bo->need_io = 0;
2344
		bo->need_io = 0;
2345
 
2345
 
2346
decouple:
2346
decouple:
2347
		DBG(("%s: releasing handle=%d\n",
2347
		DBG(("%s: releasing handle=%d\n",
2348
		     __FUNCTION__, bo->base.handle));
2348
		     __FUNCTION__, bo->base.handle));
2349
		list_del(&bo->base.list);
2349
		list_del(&bo->base.list);
2350
		kgem_bo_unref(kgem, &bo->base);
2350
		kgem_bo_unref(kgem, &bo->base);
2351
	}
2351
	}
2352
}
2352
}
2353
 
2353
 
2354
static void kgem_cleanup(struct kgem *kgem)
2354
static void kgem_cleanup(struct kgem *kgem)
2355
{
2355
{
2356
	int n;
2356
	int n;
2357
 
2357
 
2358
	for (n = 0; n < ARRAY_SIZE(kgem->requests); n++) {
2358
	for (n = 0; n < ARRAY_SIZE(kgem->requests); n++) {
2359
		while (!list_is_empty(&kgem->requests[n])) {
2359
		while (!list_is_empty(&kgem->requests[n])) {
2360
			struct kgem_request *rq;
2360
			struct kgem_request *rq;
2361
 
2361
 
2362
			rq = list_first_entry(&kgem->requests[n],
2362
			rq = list_first_entry(&kgem->requests[n],
2363
					      struct kgem_request,
2363
					      struct kgem_request,
2364
					      list);
2364
					      list);
2365
			while (!list_is_empty(&rq->buffers)) {
2365
			while (!list_is_empty(&rq->buffers)) {
2366
				struct kgem_bo *bo;
2366
				struct kgem_bo *bo;
2367
 
2367
 
2368
				bo = list_first_entry(&rq->buffers,
2368
				bo = list_first_entry(&rq->buffers,
2369
						      struct kgem_bo,
2369
						      struct kgem_bo,
2370
						      request);
2370
						      request);
2371
 
2371
 
2372
				bo->exec = NULL;
2372
				bo->exec = NULL;
2373
				bo->gpu_dirty = false;
2373
				bo->gpu_dirty = false;
2374
				__kgem_bo_clear_busy(bo);
2374
				__kgem_bo_clear_busy(bo);
2375
				if (bo->refcnt == 0)
2375
				if (bo->refcnt == 0)
2376
					kgem_bo_free(kgem, bo);
2376
					kgem_bo_free(kgem, bo);
2377
			}
2377
			}
2378
 
2378
 
2379
			__kgem_request_free(rq);
2379
			__kgem_request_free(rq);
2380
		}
2380
		}
2381
	}
2381
	}
2382
 
2382
 
2383
	kgem_close_inactive(kgem);
2383
	kgem_close_inactive(kgem);
2384
}
2384
}
2385
 
2385
 
2386
static int kgem_batch_write(struct kgem *kgem, uint32_t handle, uint32_t size)
2386
static int kgem_batch_write(struct kgem *kgem, uint32_t handle, uint32_t size)
2387
{
2387
{
2388
	int ret;
2388
	int ret;
2389
 
2389
 
2390
	ASSERT_IDLE(kgem, handle);
2390
	ASSERT_IDLE(kgem, handle);
2391
 
2391
 
2392
	/* If there is no surface data, just upload the batch */
2392
	/* If there is no surface data, just upload the batch */
2393
	if (kgem->surface == kgem->batch_size)
2393
	if (kgem->surface == kgem->batch_size)
2394
		return gem_write(kgem->fd, handle,
2394
		return gem_write(kgem->fd, handle,
2395
				 0, sizeof(uint32_t)*kgem->nbatch,
2395
				 0, sizeof(uint32_t)*kgem->nbatch,
2396
				 kgem->batch);
2396
				 kgem->batch);
2397
 
2397
 
2398
	/* Are the batch pages conjoint with the surface pages? */
2398
	/* Are the batch pages conjoint with the surface pages? */
2399
	if (kgem->surface < kgem->nbatch + PAGE_SIZE/sizeof(uint32_t)) {
2399
	if (kgem->surface < kgem->nbatch + PAGE_SIZE/sizeof(uint32_t)) {
2400
		assert(size == PAGE_ALIGN(kgem->batch_size*sizeof(uint32_t)));
2400
		assert(size == PAGE_ALIGN(kgem->batch_size*sizeof(uint32_t)));
2401
		return gem_write(kgem->fd, handle,
2401
		return gem_write(kgem->fd, handle,
2402
				 0, kgem->batch_size*sizeof(uint32_t),
2402
				 0, kgem->batch_size*sizeof(uint32_t),
2403
				 kgem->batch);
2403
				 kgem->batch);
2404
	}
2404
	}
2405
 
2405
 
2406
	/* Disjoint surface/batch, upload separately */
2406
	/* Disjoint surface/batch, upload separately */
2407
	ret = gem_write(kgem->fd, handle,
2407
	ret = gem_write(kgem->fd, handle,
2408
			0, sizeof(uint32_t)*kgem->nbatch,
2408
			0, sizeof(uint32_t)*kgem->nbatch,
2409
			kgem->batch);
2409
			kgem->batch);
2410
	if (ret)
2410
	if (ret)
2411
		return ret;
2411
		return ret;
2412
 
2412
 
2413
	ret = PAGE_ALIGN(sizeof(uint32_t) * kgem->batch_size);
2413
	ret = PAGE_ALIGN(sizeof(uint32_t) * kgem->batch_size);
2414
	ret -= sizeof(uint32_t) * kgem->surface;
2414
	ret -= sizeof(uint32_t) * kgem->surface;
2415
	assert(size-ret >= kgem->nbatch*sizeof(uint32_t));
2415
	assert(size-ret >= kgem->nbatch*sizeof(uint32_t));
2416
	return __gem_write(kgem->fd, handle,
2416
	return __gem_write(kgem->fd, handle,
2417
			size - ret, (kgem->batch_size - kgem->surface)*sizeof(uint32_t),
2417
			size - ret, (kgem->batch_size - kgem->surface)*sizeof(uint32_t),
2418
			kgem->batch + kgem->surface);
2418
			kgem->batch + kgem->surface);
2419
}
2419
}
2420
 
2420
 
2421
void kgem_reset(struct kgem *kgem)
2421
void kgem_reset(struct kgem *kgem)
2422
{
2422
{
2423
	if (kgem->next_request) {
2423
	if (kgem->next_request) {
2424
		struct kgem_request *rq = kgem->next_request;
2424
		struct kgem_request *rq = kgem->next_request;
2425
 
2425
 
2426
		while (!list_is_empty(&rq->buffers)) {
2426
		while (!list_is_empty(&rq->buffers)) {
2427
			struct kgem_bo *bo =
2427
			struct kgem_bo *bo =
2428
				list_first_entry(&rq->buffers,
2428
				list_first_entry(&rq->buffers,
2429
						 struct kgem_bo,
2429
						 struct kgem_bo,
2430
						 request);
2430
						 request);
2431
			list_del(&bo->request);
2431
			list_del(&bo->request);
2432
 
2432
 
2433
			assert(RQ(bo->rq) == rq);
2433
			assert(RQ(bo->rq) == rq);
2434
 
2434
 
2435
			bo->binding.offset = 0;
2435
			bo->binding.offset = 0;
2436
			bo->exec = NULL;
2436
			bo->exec = NULL;
2437
			bo->target_handle = -1;
2437
			bo->target_handle = -1;
2438
			bo->gpu_dirty = false;
2438
			bo->gpu_dirty = false;
2439
 
2439
 
2440
			if (bo->needs_flush && __kgem_busy(kgem, bo->handle)) {
2440
			if (bo->needs_flush && __kgem_busy(kgem, bo->handle)) {
2441
				assert(bo->domain == DOMAIN_GPU || bo->domain == DOMAIN_NONE);
2441
				assert(bo->domain == DOMAIN_GPU || bo->domain == DOMAIN_NONE);
2442
				list_add(&bo->request, &kgem->flushing);
2442
				list_add(&bo->request, &kgem->flushing);
2443
				bo->rq = (void *)kgem;
2443
				bo->rq = (void *)kgem;
2444
			} else
2444
			} else
2445
				__kgem_bo_clear_busy(bo);
2445
				__kgem_bo_clear_busy(bo);
2446
 
2446
 
2447
			if (bo->refcnt || bo->rq)
2447
			if (bo->refcnt || bo->rq)
2448
				continue;
2448
				continue;
2449
 
2449
 
2450
			if (bo->snoop) {
2450
			if (bo->snoop) {
2451
				kgem_bo_move_to_snoop(kgem, bo);
2451
				kgem_bo_move_to_snoop(kgem, bo);
2452
			} else if (bo->scanout) {
2452
			} else if (bo->scanout) {
2453
				kgem_bo_move_to_scanout(kgem, bo);
2453
				kgem_bo_move_to_scanout(kgem, bo);
2454
			} else if ((bo = kgem_bo_replace_io(bo))->reusable &&
2454
			} else if ((bo = kgem_bo_replace_io(bo))->reusable &&
2455
				   kgem_bo_set_purgeable(kgem, bo)) {
2455
				   kgem_bo_set_purgeable(kgem, bo)) {
2456
				kgem_bo_move_to_inactive(kgem, bo);
2456
				kgem_bo_move_to_inactive(kgem, bo);
2457
			} else {
2457
			} else {
2458
				DBG(("%s: closing %d\n",
2458
				DBG(("%s: closing %d\n",
2459
				     __FUNCTION__, bo->handle));
2459
				     __FUNCTION__, bo->handle));
2460
				kgem_bo_free(kgem, bo);
2460
				kgem_bo_free(kgem, bo);
2461
			}
2461
			}
2462
		}
2462
		}
2463
 
2463
 
2464
		if (rq != &kgem->static_request) {
2464
		if (rq != &kgem->static_request) {
2465
			list_init(&rq->list);
2465
			list_init(&rq->list);
2466
			__kgem_request_free(rq);
2466
			__kgem_request_free(rq);
2467
		}
2467
		}
2468
	}
2468
	}
2469
 
2469
 
2470
	kgem->nfence = 0;
2470
	kgem->nfence = 0;
2471
	kgem->nexec = 0;
2471
	kgem->nexec = 0;
2472
	kgem->nreloc = 0;
2472
	kgem->nreloc = 0;
2473
	kgem->nreloc__self = 0;
2473
	kgem->nreloc__self = 0;
2474
	kgem->aperture = 0;
2474
	kgem->aperture = 0;
2475
	kgem->aperture_fenced = 0;
2475
	kgem->aperture_fenced = 0;
2476
	kgem->nbatch = 0;
2476
	kgem->nbatch = 0;
2477
	kgem->surface = kgem->batch_size;
2477
	kgem->surface = kgem->batch_size;
2478
	kgem->mode = KGEM_NONE;
2478
	kgem->mode = KGEM_NONE;
2479
	kgem->flush = 0;
2479
	kgem->flush = 0;
2480
	kgem->batch_flags = kgem->batch_flags_base;
2480
	kgem->batch_flags = kgem->batch_flags_base;
2481
 
2481
 
2482
	kgem->next_request = __kgem_request_alloc(kgem);
2482
	kgem->next_request = __kgem_request_alloc(kgem);
2483
 
2483
 
2484
	kgem_sna_reset(kgem);
2484
	kgem_sna_reset(kgem);
2485
}
2485
}
2486
 
2486
 
2487
static int compact_batch_surface(struct kgem *kgem)
2487
static int compact_batch_surface(struct kgem *kgem)
2488
{
2488
{
2489
	int size, shrink, n;
2489
	int size, shrink, n;
2490
 
2490
 
2491
	if (!kgem->has_relaxed_delta)
2491
	if (!kgem->has_relaxed_delta)
2492
		return kgem->batch_size;
2492
		return kgem->batch_size;
2493
 
2493
 
2494
	/* See if we can pack the contents into one or two pages */
2494
	/* See if we can pack the contents into one or two pages */
2495
	n = ALIGN(kgem->batch_size, 1024);
2495
	n = ALIGN(kgem->batch_size, 1024);
2496
	size = n - kgem->surface + kgem->nbatch;
2496
	size = n - kgem->surface + kgem->nbatch;
2497
	size = ALIGN(size, 1024);
2497
	size = ALIGN(size, 1024);
2498
 
2498
 
2499
	shrink = n - size;
2499
	shrink = n - size;
2500
	if (shrink) {
2500
	if (shrink) {
2501
		DBG(("shrinking from %d to %d\n", kgem->batch_size, size));
2501
		DBG(("shrinking from %d to %d\n", kgem->batch_size, size));
2502
 
2502
 
2503
		shrink *= sizeof(uint32_t);
2503
		shrink *= sizeof(uint32_t);
2504
		for (n = 0; n < kgem->nreloc; n++) {
2504
		for (n = 0; n < kgem->nreloc; n++) {
2505
			if (kgem->reloc[n].read_domains == I915_GEM_DOMAIN_INSTRUCTION &&
2505
			if (kgem->reloc[n].read_domains == I915_GEM_DOMAIN_INSTRUCTION &&
2506
			    kgem->reloc[n].target_handle == ~0U)
2506
			    kgem->reloc[n].target_handle == ~0U)
2507
				kgem->reloc[n].delta -= shrink;
2507
				kgem->reloc[n].delta -= shrink;
2508
 
2508
 
2509
			if (kgem->reloc[n].offset >= sizeof(uint32_t)*kgem->nbatch)
2509
			if (kgem->reloc[n].offset >= sizeof(uint32_t)*kgem->nbatch)
2510
				kgem->reloc[n].offset -= shrink;
2510
				kgem->reloc[n].offset -= shrink;
2511
		}
2511
		}
2512
	}
2512
	}
2513
 
2513
 
2514
	return size * sizeof(uint32_t);
2514
	return size * sizeof(uint32_t);
2515
}
2515
}
2516
 
2516
 
2517
static struct kgem_bo *
2517
static struct kgem_bo *
2518
kgem_create_batch(struct kgem *kgem, int size)
2518
kgem_create_batch(struct kgem *kgem, int size)
2519
{
2519
{
2520
	struct drm_i915_gem_set_domain set_domain;
2520
	struct drm_i915_gem_set_domain set_domain;
2521
	struct kgem_bo *bo;
2521
	struct kgem_bo *bo;
2522
 
2522
 
2523
	if (size <= 4096) {
2523
	if (size <= 4096) {
2524
		bo = list_first_entry(&kgem->pinned_batches[0],
2524
		bo = list_first_entry(&kgem->pinned_batches[0],
2525
				      struct kgem_bo,
2525
				      struct kgem_bo,
2526
				      list);
2526
				      list);
2527
		if (!bo->rq) {
2527
		if (!bo->rq) {
2528
out_4096:
2528
out_4096:
2529
			list_move_tail(&bo->list, &kgem->pinned_batches[0]);
2529
			list_move_tail(&bo->list, &kgem->pinned_batches[0]);
2530
			return kgem_bo_reference(bo);
2530
			return kgem_bo_reference(bo);
2531
		}
2531
		}
2532
 
2532
 
2533
		if (!__kgem_busy(kgem, bo->handle)) {
2533
		if (!__kgem_busy(kgem, bo->handle)) {
2534
			assert(RQ(bo->rq)->bo == bo);
2534
			assert(RQ(bo->rq)->bo == bo);
2535
			__kgem_retire_rq(kgem, RQ(bo->rq));
2535
			__kgem_retire_rq(kgem, RQ(bo->rq));
2536
			goto out_4096;
2536
			goto out_4096;
2537
		}
2537
		}
2538
	}
2538
	}
2539
 
2539
 
2540
	if (size <= 16384) {
2540
	if (size <= 16384) {
2541
		bo = list_first_entry(&kgem->pinned_batches[1],
2541
		bo = list_first_entry(&kgem->pinned_batches[1],
2542
				      struct kgem_bo,
2542
				      struct kgem_bo,
2543
				      list);
2543
				      list);
2544
		if (!bo->rq) {
2544
		if (!bo->rq) {
2545
out_16384:
2545
out_16384:
2546
			list_move_tail(&bo->list, &kgem->pinned_batches[1]);
2546
			list_move_tail(&bo->list, &kgem->pinned_batches[1]);
2547
			return kgem_bo_reference(bo);
2547
			return kgem_bo_reference(bo);
2548
		}
2548
		}
2549
 
2549
 
2550
		if (!__kgem_busy(kgem, bo->handle)) {
2550
		if (!__kgem_busy(kgem, bo->handle)) {
2551
			assert(RQ(bo->rq)->bo == bo);
2551
			assert(RQ(bo->rq)->bo == bo);
2552
			__kgem_retire_rq(kgem, RQ(bo->rq));
2552
			__kgem_retire_rq(kgem, RQ(bo->rq));
2553
			goto out_16384;
2553
			goto out_16384;
2554
		}
2554
		}
2555
	}
2555
	}
2556
 
2556
 
2557
	if (kgem->gen == 020 && !kgem->has_pinned_batches) {
2557
	if (kgem->gen == 020 && !kgem->has_pinned_batches) {
2558
		assert(size <= 16384);
2558
		assert(size <= 16384);
2559
 
2559
 
2560
		bo = list_first_entry(&kgem->pinned_batches[size > 4096],
2560
		bo = list_first_entry(&kgem->pinned_batches[size > 4096],
2561
				      struct kgem_bo,
2561
				      struct kgem_bo,
2562
				      list);
2562
				      list);
2563
		list_move_tail(&bo->list, &kgem->pinned_batches[size > 4096]);
2563
		list_move_tail(&bo->list, &kgem->pinned_batches[size > 4096]);
2564
 
2564
 
2565
		DBG(("%s: syncing due to busy batches\n", __FUNCTION__));
2565
		DBG(("%s: syncing due to busy batches\n", __FUNCTION__));
2566
 
2566
 
2567
		VG_CLEAR(set_domain);
2567
		VG_CLEAR(set_domain);
2568
		set_domain.handle = bo->handle;
2568
		set_domain.handle = bo->handle;
2569
		set_domain.read_domains = I915_GEM_DOMAIN_GTT;
2569
		set_domain.read_domains = I915_GEM_DOMAIN_GTT;
2570
		set_domain.write_domain = I915_GEM_DOMAIN_GTT;
2570
		set_domain.write_domain = I915_GEM_DOMAIN_GTT;
2571
		if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
2571
		if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
2572
			DBG(("%s: sync: GPU hang detected\n", __FUNCTION__));
2572
			DBG(("%s: sync: GPU hang detected\n", __FUNCTION__));
2573
			kgem_throttle(kgem);
2573
			kgem_throttle(kgem);
2574
			return NULL;
2574
			return NULL;
2575
		}
2575
		}
2576
 
2576
 
2577
		kgem_retire(kgem);
2577
		kgem_retire(kgem);
2578
		assert(bo->rq == NULL);
2578
		assert(bo->rq == NULL);
2579
		return kgem_bo_reference(bo);
2579
		return kgem_bo_reference(bo);
2580
	}
2580
	}
2581
 
2581
 
2582
	return kgem_create_linear(kgem, size, CREATE_NO_THROTTLE);
2582
	return kgem_create_linear(kgem, size, CREATE_NO_THROTTLE);
2583
}
2583
}
2584
 
2584
 
2585
void _kgem_submit(struct kgem *kgem)
2585
void _kgem_submit(struct kgem *kgem)
2586
{
2586
{
2587
	struct kgem_request *rq;
2587
	struct kgem_request *rq;
2588
	uint32_t batch_end;
2588
	uint32_t batch_end;
2589
	int size;
2589
	int size;
2590
 
2590
 
2591
	assert(!DBG_NO_HW);
2591
	assert(!DBG_NO_HW);
2592
	assert(!kgem->wedged);
2592
	assert(!kgem->wedged);
2593
 
2593
 
2594
	assert(kgem->nbatch);
2594
	assert(kgem->nbatch);
2595
	assert(kgem->nbatch <= KGEM_BATCH_SIZE(kgem));
2595
	assert(kgem->nbatch <= KGEM_BATCH_SIZE(kgem));
2596
	assert(kgem->nbatch <= kgem->surface);
2596
	assert(kgem->nbatch <= kgem->surface);
2597
 
2597
 
2598
	batch_end = kgem_end_batch(kgem);
2598
	batch_end = kgem_end_batch(kgem);
2599
	kgem_sna_flush(kgem);
2599
	kgem_sna_flush(kgem);
2600
 
2600
 
2601
	DBG(("batch[%d/%d, flags=%x]: %d %d %d %d, nreloc=%d, nexec=%d, nfence=%d, aperture=%d\n",
2601
	DBG(("batch[%d/%d, flags=%x]: %d %d %d %d, nreloc=%d, nexec=%d, nfence=%d, aperture=%d\n",
2602
	     kgem->mode, kgem->ring, kgem->batch_flags,
2602
	     kgem->mode, kgem->ring, kgem->batch_flags,
2603
	     batch_end, kgem->nbatch, kgem->surface, kgem->batch_size,
2603
	     batch_end, kgem->nbatch, kgem->surface, kgem->batch_size,
2604
	     kgem->nreloc, kgem->nexec, kgem->nfence, kgem->aperture));
2604
	     kgem->nreloc, kgem->nexec, kgem->nfence, kgem->aperture));
2605
 
2605
 
2606
	assert(kgem->nbatch <= kgem->batch_size);
2606
	assert(kgem->nbatch <= kgem->batch_size);
2607
	assert(kgem->nbatch <= kgem->surface);
2607
	assert(kgem->nbatch <= kgem->surface);
2608
	assert(kgem->nreloc <= ARRAY_SIZE(kgem->reloc));
2608
	assert(kgem->nreloc <= ARRAY_SIZE(kgem->reloc));
2609
	assert(kgem->nexec < ARRAY_SIZE(kgem->exec));
2609
	assert(kgem->nexec < ARRAY_SIZE(kgem->exec));
2610
	assert(kgem->nfence <= kgem->fence_max);
2610
	assert(kgem->nfence <= kgem->fence_max);
2611
 
2611
 
2612
	kgem_finish_buffers(kgem);
2612
	kgem_finish_buffers(kgem);
2613
 
2613
 
2614
#if SHOW_BATCH
2614
#if SHOW_BATCH
2615
	__kgem_batch_debug(kgem, batch_end);
2615
	__kgem_batch_debug(kgem, batch_end);
2616
#endif
2616
#endif
2617
 
2617
 
2618
	rq = kgem->next_request;
2618
	rq = kgem->next_request;
2619
	if (kgem->surface != kgem->batch_size)
2619
	if (kgem->surface != kgem->batch_size)
2620
		size = compact_batch_surface(kgem);
2620
		size = compact_batch_surface(kgem);
2621
	else
2621
	else
2622
		size = kgem->nbatch * sizeof(kgem->batch[0]);
2622
		size = kgem->nbatch * sizeof(kgem->batch[0]);
2623
	rq->bo = kgem_create_batch(kgem, size);
2623
	rq->bo = kgem_create_batch(kgem, size);
2624
	if (rq->bo) {
2624
	if (rq->bo) {
2625
		uint32_t handle = rq->bo->handle;
2625
		uint32_t handle = rq->bo->handle;
2626
		int i;
2626
		int i;
2627
 
2627
 
2628
		assert(!rq->bo->needs_flush);
2628
		assert(!rq->bo->needs_flush);
2629
 
2629
 
2630
		i = kgem->nexec++;
2630
		i = kgem->nexec++;
2631
		kgem->exec[i].handle = handle;
2631
		kgem->exec[i].handle = handle;
2632
		kgem->exec[i].relocation_count = kgem->nreloc;
2632
		kgem->exec[i].relocation_count = kgem->nreloc;
2633
		kgem->exec[i].relocs_ptr = (uintptr_t)kgem->reloc;
2633
		kgem->exec[i].relocs_ptr = (uintptr_t)kgem->reloc;
2634
		kgem->exec[i].alignment = 0;
2634
		kgem->exec[i].alignment = 0;
2635
		kgem->exec[i].offset = rq->bo->presumed_offset;
2635
		kgem->exec[i].offset = rq->bo->presumed_offset;
2636
		kgem->exec[i].flags = 0;
2636
		kgem->exec[i].flags = 0;
2637
		kgem->exec[i].rsvd1 = 0;
2637
		kgem->exec[i].rsvd1 = 0;
2638
		kgem->exec[i].rsvd2 = 0;
2638
		kgem->exec[i].rsvd2 = 0;
2639
 
2639
 
2640
		rq->bo->target_handle = kgem->has_handle_lut ? i : handle;
2640
		rq->bo->target_handle = kgem->has_handle_lut ? i : handle;
2641
		rq->bo->exec = &kgem->exec[i];
2641
		rq->bo->exec = &kgem->exec[i];
2642
		rq->bo->rq = MAKE_REQUEST(rq, kgem->ring); /* useful sanity check */
2642
		rq->bo->rq = MAKE_REQUEST(rq, kgem->ring); /* useful sanity check */
2643
		list_add(&rq->bo->request, &rq->buffers);
2643
		list_add(&rq->bo->request, &rq->buffers);
2644
		rq->ring = kgem->ring == KGEM_BLT;
2644
		rq->ring = kgem->ring == KGEM_BLT;
2645
 
2645
 
2646
		kgem_fixup_self_relocs(kgem, rq->bo);
2646
		kgem_fixup_self_relocs(kgem, rq->bo);
2647
 
2647
 
2648
		if (kgem_batch_write(kgem, handle, size) == 0) {
2648
		if (kgem_batch_write(kgem, handle, size) == 0) {
2649
			struct drm_i915_gem_execbuffer2 execbuf;
2649
			struct drm_i915_gem_execbuffer2 execbuf;
2650
			int ret, retry = 3;
2650
			int ret, retry = 3;
2651
 
2651
 
2652
			memset(&execbuf, 0, sizeof(execbuf));
2652
			memset(&execbuf, 0, sizeof(execbuf));
2653
			execbuf.buffers_ptr = (uintptr_t)kgem->exec;
2653
			execbuf.buffers_ptr = (uintptr_t)kgem->exec;
2654
			execbuf.buffer_count = kgem->nexec;
2654
			execbuf.buffer_count = kgem->nexec;
2655
			execbuf.batch_len = batch_end*sizeof(uint32_t);
2655
			execbuf.batch_len = batch_end*sizeof(uint32_t);
2656
			execbuf.flags = kgem->ring | kgem->batch_flags;
2656
			execbuf.flags = kgem->ring | kgem->batch_flags;
2657
 
2657
 
2658
 
2658
 
2659
			ret = drmIoctl(kgem->fd,
2659
			ret = drmIoctl(kgem->fd,
2660
				       DRM_IOCTL_I915_GEM_EXECBUFFER2,
2660
				       DRM_IOCTL_I915_GEM_EXECBUFFER2,
2661
				       &execbuf);
2661
				       &execbuf);
2662
			while (ret == -1 && errno == EBUSY && retry--) {
2662
			while (ret == -1 && errno == EBUSY && retry--) {
2663
				__kgem_throttle(kgem);
2663
				__kgem_throttle(kgem);
2664
				ret = drmIoctl(kgem->fd,
2664
				ret = drmIoctl(kgem->fd,
2665
					       DRM_IOCTL_I915_GEM_EXECBUFFER2,
2665
					       DRM_IOCTL_I915_GEM_EXECBUFFER2,
2666
					       &execbuf);
2666
					       &execbuf);
2667
			}
2667
			}
2668
			if (DEBUG_SYNC && ret == 0) {
2668
			if (DEBUG_SYNC && ret == 0) {
2669
				struct drm_i915_gem_set_domain set_domain;
2669
				struct drm_i915_gem_set_domain set_domain;
2670
 
2670
 
2671
				VG_CLEAR(set_domain);
2671
				VG_CLEAR(set_domain);
2672
				set_domain.handle = handle;
2672
				set_domain.handle = handle;
2673
				set_domain.read_domains = I915_GEM_DOMAIN_GTT;
2673
				set_domain.read_domains = I915_GEM_DOMAIN_GTT;
2674
				set_domain.write_domain = I915_GEM_DOMAIN_GTT;
2674
				set_domain.write_domain = I915_GEM_DOMAIN_GTT;
2675
 
2675
 
2676
				ret = drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain);
2676
				ret = drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain);
2677
			}
2677
			}
2678
			if (ret == -1) {
2678
			if (ret == -1) {
2679
//				DBG(("%s: GPU hang detected [%d]\n",
2679
//				DBG(("%s: GPU hang detected [%d]\n",
2680
//				     __FUNCTION__, errno));
2680
//				     __FUNCTION__, errno));
2681
				kgem_throttle(kgem);
2681
				kgem_throttle(kgem);
2682
				kgem->wedged = true;
2682
				kgem->wedged = true;
2683
 
2683
 
2684
#if 0
2684
#if 0
2685
				ret = errno;
2685
				ret = errno;
2686
				ErrorF("batch[%d/%d]: %d %d %d, nreloc=%d, nexec=%d, nfence=%d, aperture=%d: errno=%d\n",
2686
				ErrorF("batch[%d/%d]: %d %d %d, nreloc=%d, nexec=%d, nfence=%d, aperture=%d: errno=%d\n",
2687
				       kgem->mode, kgem->ring, batch_end, kgem->nbatch, kgem->surface,
2687
				       kgem->mode, kgem->ring, batch_end, kgem->nbatch, kgem->surface,
2688
				       kgem->nreloc, kgem->nexec, kgem->nfence, kgem->aperture, errno);
2688
				       kgem->nreloc, kgem->nexec, kgem->nfence, kgem->aperture, errno);
2689
 
2689
 
2690
				for (i = 0; i < kgem->nexec; i++) {
2690
				for (i = 0; i < kgem->nexec; i++) {
2691
					struct kgem_bo *bo, *found = NULL;
2691
					struct kgem_bo *bo, *found = NULL;
2692
 
2692
 
2693
					list_for_each_entry(bo, &kgem->next_request->buffers, request) {
2693
					list_for_each_entry(bo, &kgem->next_request->buffers, request) {
2694
						if (bo->handle == kgem->exec[i].handle) {
2694
						if (bo->handle == kgem->exec[i].handle) {
2695
							found = bo;
2695
							found = bo;
2696
							break;
2696
							break;
2697
						}
2697
						}
2698
					}
2698
					}
2699
					ErrorF("exec[%d] = handle:%d, presumed offset: %x, size: %d, tiling %d, fenced %d, snooped %d, deleted %d\n",
2699
					ErrorF("exec[%d] = handle:%d, presumed offset: %x, size: %d, tiling %d, fenced %d, snooped %d, deleted %d\n",
2700
					       i,
2700
					       i,
2701
					       kgem->exec[i].handle,
2701
					       kgem->exec[i].handle,
2702
					       (int)kgem->exec[i].offset,
2702
					       (int)kgem->exec[i].offset,
2703
					       found ? kgem_bo_size(found) : -1,
2703
					       found ? kgem_bo_size(found) : -1,
2704
					       found ? found->tiling : -1,
2704
					       found ? found->tiling : -1,
2705
					       (int)(kgem->exec[i].flags & EXEC_OBJECT_NEEDS_FENCE),
2705
					       (int)(kgem->exec[i].flags & EXEC_OBJECT_NEEDS_FENCE),
2706
					       found ? found->snoop : -1,
2706
					       found ? found->snoop : -1,
2707
					       found ? found->purged : -1);
2707
					       found ? found->purged : -1);
2708
				}
2708
				}
2709
				for (i = 0; i < kgem->nreloc; i++) {
2709
				for (i = 0; i < kgem->nreloc; i++) {
2710
					ErrorF("reloc[%d] = pos:%d, target:%d, delta:%d, read:%x, write:%x, offset:%x\n",
2710
					ErrorF("reloc[%d] = pos:%d, target:%d, delta:%d, read:%x, write:%x, offset:%x\n",
2711
					       i,
2711
					       i,
2712
					       (int)kgem->reloc[i].offset,
2712
					       (int)kgem->reloc[i].offset,
2713
					       kgem->reloc[i].target_handle,
2713
					       kgem->reloc[i].target_handle,
2714
					       kgem->reloc[i].delta,
2714
					       kgem->reloc[i].delta,
2715
					       kgem->reloc[i].read_domains,
2715
					       kgem->reloc[i].read_domains,
2716
					       kgem->reloc[i].write_domain,
2716
					       kgem->reloc[i].write_domain,
2717
					       (int)kgem->reloc[i].presumed_offset);
2717
					       (int)kgem->reloc[i].presumed_offset);
2718
				}
2718
				}
2719
 
2719
 
2720
				if (DEBUG_SYNC) {
2720
				if (DEBUG_SYNC) {
2721
					int fd = open("/tmp/batchbuffer", O_WRONLY | O_CREAT | O_APPEND, 0666);
2721
					int fd = open("/tmp/batchbuffer", O_WRONLY | O_CREAT | O_APPEND, 0666);
2722
					if (fd != -1) {
2722
					if (fd != -1) {
2723
						write(fd, kgem->batch, batch_end*sizeof(uint32_t));
2723
						write(fd, kgem->batch, batch_end*sizeof(uint32_t));
2724
						close(fd);
2724
						close(fd);
2725
					}
2725
					}
2726
 
2726
 
2727
					FatalError("SNA: failed to submit batchbuffer, errno=%d\n", ret);
2727
					FatalError("SNA: failed to submit batchbuffer, errno=%d\n", ret);
2728
				}
2728
				}
2729
#endif
2729
#endif
2730
			}
2730
			}
2731
		}
2731
		}
2732
 
2732
 
2733
		kgem_commit(kgem);
2733
		kgem_commit(kgem);
2734
	}
2734
	}
2735
	if (kgem->wedged)
2735
	if (kgem->wedged)
2736
		kgem_cleanup(kgem);
2736
		kgem_cleanup(kgem);
2737
 
2737
 
2738
	kgem_reset(kgem);
2738
	kgem_reset(kgem);
2739
 
2739
 
2740
	assert(kgem->next_request != NULL);
2740
	assert(kgem->next_request != NULL);
2741
}
2741
}
2742
 
2742
 
2743
void kgem_throttle(struct kgem *kgem)
2743
void kgem_throttle(struct kgem *kgem)
2744
{
2744
{
2745
	kgem->need_throttle = 0;
2745
	kgem->need_throttle = 0;
2746
	if (kgem->wedged)
2746
	if (kgem->wedged)
2747
		return;
2747
		return;
2748
 
2748
 
2749
	kgem->wedged = __kgem_throttle(kgem);
2749
	kgem->wedged = __kgem_throttle(kgem);
2750
	if (kgem->wedged) {
2750
	if (kgem->wedged) {
2751
		printf("Detected a hung GPU, disabling acceleration.\n");
2751
		printf("Detected a hung GPU, disabling acceleration.\n");
2752
		printf("When reporting this, please include i915_error_state from debugfs and the full dmesg.\n");
2752
		printf("When reporting this, please include i915_error_state from debugfs and the full dmesg.\n");
2753
	}
2753
	}
2754
}
2754
}
2755
 
2755
 
2756
void kgem_purge_cache(struct kgem *kgem)
2756
void kgem_purge_cache(struct kgem *kgem)
2757
{
2757
{
2758
	struct kgem_bo *bo, *next;
2758
	struct kgem_bo *bo, *next;
2759
	int i;
2759
	int i;
2760
 
2760
 
2761
	for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
2761
	for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
2762
		list_for_each_entry_safe(bo, next, &kgem->inactive[i], list) {
2762
		list_for_each_entry_safe(bo, next, &kgem->inactive[i], list) {
2763
			if (!kgem_bo_is_retained(kgem, bo)) {
2763
			if (!kgem_bo_is_retained(kgem, bo)) {
2764
				DBG(("%s: purging %d\n",
2764
				DBG(("%s: purging %d\n",
2765
				     __FUNCTION__, bo->handle));
2765
				     __FUNCTION__, bo->handle));
2766
				kgem_bo_free(kgem, bo);
2766
				kgem_bo_free(kgem, bo);
2767
			}
2767
			}
2768
		}
2768
		}
2769
	}
2769
	}
2770
 
2770
 
2771
	kgem->need_purge = false;
2771
	kgem->need_purge = false;
2772
}
2772
}
2773
 
2773
 
2774
 
2774
 
2775
void kgem_clean_large_cache(struct kgem *kgem)
2775
void kgem_clean_large_cache(struct kgem *kgem)
2776
{
2776
{
2777
	while (!list_is_empty(&kgem->large_inactive)) {
2777
	while (!list_is_empty(&kgem->large_inactive)) {
2778
		kgem_bo_free(kgem,
2778
		kgem_bo_free(kgem,
2779
			     list_first_entry(&kgem->large_inactive,
2779
			     list_first_entry(&kgem->large_inactive,
2780
					      struct kgem_bo, list));
2780
					      struct kgem_bo, list));
2781
 
2781
 
2782
	}
2782
	}
2783
}
2783
}
2784
 
2784
 
2785
bool kgem_expire_cache(struct kgem *kgem)
2785
bool kgem_expire_cache(struct kgem *kgem)
2786
{
2786
{
2787
	time_t now, expire;
2787
	time_t now, expire;
2788
	struct kgem_bo *bo;
2788
	struct kgem_bo *bo;
2789
	unsigned int size = 0, count = 0;
2789
	unsigned int size = 0, count = 0;
2790
	bool idle;
2790
	bool idle;
2791
	unsigned int i;
2791
	unsigned int i;
2792
 
2792
 
2793
	time(&now);
2793
	time(&now);
2794
 
2794
 
2795
	while (__kgem_freed_bo) {
2795
	while (__kgem_freed_bo) {
2796
		bo = __kgem_freed_bo;
2796
		bo = __kgem_freed_bo;
2797
		__kgem_freed_bo = *(struct kgem_bo **)bo;
2797
		__kgem_freed_bo = *(struct kgem_bo **)bo;
2798
		free(bo);
2798
		free(bo);
2799
	}
2799
	}
2800
 
2800
 
2801
	while (__kgem_freed_request) {
2801
	while (__kgem_freed_request) {
2802
		struct kgem_request *rq = __kgem_freed_request;
2802
		struct kgem_request *rq = __kgem_freed_request;
2803
		__kgem_freed_request = *(struct kgem_request **)rq;
2803
		__kgem_freed_request = *(struct kgem_request **)rq;
2804
		free(rq);
2804
		free(rq);
2805
	}
2805
	}
2806
 
2806
 
2807
	kgem_clean_large_cache(kgem);
2807
	kgem_clean_large_cache(kgem);
2808
 
2808
 
2809
	expire = 0;
2809
	expire = 0;
2810
	list_for_each_entry(bo, &kgem->snoop, list) {
2810
	list_for_each_entry(bo, &kgem->snoop, list) {
2811
		if (bo->delta) {
2811
		if (bo->delta) {
2812
			expire = now - MAX_INACTIVE_TIME/2;
2812
			expire = now - MAX_INACTIVE_TIME/2;
2813
			break;
2813
			break;
2814
		}
2814
		}
2815
 
2815
 
2816
		bo->delta = now;
2816
		bo->delta = now;
2817
	}
2817
	}
2818
	if (expire) {
2818
	if (expire) {
2819
		while (!list_is_empty(&kgem->snoop)) {
2819
		while (!list_is_empty(&kgem->snoop)) {
2820
			bo = list_last_entry(&kgem->snoop, struct kgem_bo, list);
2820
			bo = list_last_entry(&kgem->snoop, struct kgem_bo, list);
2821
 
2821
 
2822
			if (bo->delta > expire)
2822
			if (bo->delta > expire)
2823
				break;
2823
				break;
2824
 
2824
 
2825
			kgem_bo_free(kgem, bo);
2825
			kgem_bo_free(kgem, bo);
2826
		}
2826
		}
2827
	}
2827
	}
2828
#ifdef DEBUG_MEMORY
2828
#ifdef DEBUG_MEMORY
2829
	{
2829
	{
2830
		long snoop_size = 0;
2830
		long snoop_size = 0;
2831
		int snoop_count = 0;
2831
		int snoop_count = 0;
2832
		list_for_each_entry(bo, &kgem->snoop, list)
2832
		list_for_each_entry(bo, &kgem->snoop, list)
2833
			snoop_count++, snoop_size += bytes(bo);
2833
			snoop_count++, snoop_size += bytes(bo);
2834
		ErrorF("%s: still allocated %d bo, %ld bytes, in snoop cache\n",
2834
		ErrorF("%s: still allocated %d bo, %ld bytes, in snoop cache\n",
2835
		       __FUNCTION__, snoop_count, snoop_size);
2835
		       __FUNCTION__, snoop_count, snoop_size);
2836
	}
2836
	}
2837
#endif
2837
#endif
2838
 
2838
 
2839
	kgem_retire(kgem);
2839
	kgem_retire(kgem);
2840
	if (kgem->wedged)
2840
	if (kgem->wedged)
2841
		kgem_cleanup(kgem);
2841
		kgem_cleanup(kgem);
2842
 
2842
 
2843
	kgem->expire(kgem);
2843
	kgem->expire(kgem);
2844
 
2844
 
2845
	if (kgem->need_purge)
2845
	if (kgem->need_purge)
2846
		kgem_purge_cache(kgem);
2846
		kgem_purge_cache(kgem);
2847
 
2847
 
2848
	expire = 0;
2848
	expire = 0;
2849
 
2849
 
2850
	idle = !kgem->need_retire;
2850
	idle = !kgem->need_retire;
2851
	for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
2851
	for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
2852
		idle &= list_is_empty(&kgem->inactive[i]);
2852
		idle &= list_is_empty(&kgem->inactive[i]);
2853
		list_for_each_entry(bo, &kgem->inactive[i], list) {
2853
		list_for_each_entry(bo, &kgem->inactive[i], list) {
2854
			if (bo->delta) {
2854
			if (bo->delta) {
2855
				expire = now - MAX_INACTIVE_TIME;
2855
				expire = now - MAX_INACTIVE_TIME;
2856
				break;
2856
				break;
2857
			}
2857
			}
2858
 
2858
 
2859
			bo->delta = now;
2859
			bo->delta = now;
2860
		}
2860
		}
2861
	}
2861
	}
2862
	if (idle) {
2862
	if (idle) {
2863
		DBG(("%s: idle\n", __FUNCTION__));
2863
		DBG(("%s: idle\n", __FUNCTION__));
2864
		kgem->need_expire = false;
2864
		kgem->need_expire = false;
2865
		return false;
2865
		return false;
2866
	}
2866
	}
2867
	if (expire == 0)
2867
	if (expire == 0)
2868
		return true;
2868
		return true;
2869
 
2869
 
2870
	idle = !kgem->need_retire;
2870
	idle = !kgem->need_retire;
2871
	for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
2871
	for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
2872
		struct list preserve;
2872
		struct list preserve;
2873
 
2873
 
2874
		list_init(&preserve);
2874
		list_init(&preserve);
2875
		while (!list_is_empty(&kgem->inactive[i])) {
2875
		while (!list_is_empty(&kgem->inactive[i])) {
2876
			bo = list_last_entry(&kgem->inactive[i],
2876
			bo = list_last_entry(&kgem->inactive[i],
2877
					     struct kgem_bo, list);
2877
					     struct kgem_bo, list);
2878
 
2878
 
2879
			if (bo->delta > expire) {
2879
			if (bo->delta > expire) {
2880
				idle = false;
2880
				idle = false;
2881
				break;
2881
				break;
2882
			}
2882
			}
2883
 
2883
 
2884
			if (bo->map && bo->delta + MAP_PRESERVE_TIME > expire) {
2884
			if (bo->map && bo->delta + MAP_PRESERVE_TIME > expire) {
2885
				idle = false;
2885
				idle = false;
2886
				list_move_tail(&bo->list, &preserve);
2886
				list_move_tail(&bo->list, &preserve);
2887
			} else {
2887
			} else {
2888
				count++;
2888
				count++;
2889
				size += bytes(bo);
2889
				size += bytes(bo);
2890
				kgem_bo_free(kgem, bo);
2890
				kgem_bo_free(kgem, bo);
2891
				DBG(("%s: expiring %d\n",
2891
				DBG(("%s: expiring %d\n",
2892
				     __FUNCTION__, bo->handle));
2892
				     __FUNCTION__, bo->handle));
2893
			}
2893
			}
2894
		}
2894
		}
2895
		if (!list_is_empty(&preserve)) {
2895
		if (!list_is_empty(&preserve)) {
2896
			preserve.prev->next = kgem->inactive[i].next;
2896
			preserve.prev->next = kgem->inactive[i].next;
2897
			kgem->inactive[i].next->prev = preserve.prev;
2897
			kgem->inactive[i].next->prev = preserve.prev;
2898
			kgem->inactive[i].next = preserve.next;
2898
			kgem->inactive[i].next = preserve.next;
2899
			preserve.next->prev = &kgem->inactive[i];
2899
			preserve.next->prev = &kgem->inactive[i];
2900
		}
2900
		}
2901
	}
2901
	}
2902
 
2902
 
2903
#ifdef DEBUG_MEMORY
2903
#ifdef DEBUG_MEMORY
2904
	{
2904
	{
2905
		long inactive_size = 0;
2905
		long inactive_size = 0;
2906
		int inactive_count = 0;
2906
		int inactive_count = 0;
2907
		for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++)
2907
		for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++)
2908
			list_for_each_entry(bo, &kgem->inactive[i], list)
2908
			list_for_each_entry(bo, &kgem->inactive[i], list)
2909
				inactive_count++, inactive_size += bytes(bo);
2909
				inactive_count++, inactive_size += bytes(bo);
2910
		ErrorF("%s: still allocated %d bo, %ld bytes, in inactive cache\n",
2910
		ErrorF("%s: still allocated %d bo, %ld bytes, in inactive cache\n",
2911
		       __FUNCTION__, inactive_count, inactive_size);
2911
		       __FUNCTION__, inactive_count, inactive_size);
2912
	}
2912
	}
2913
#endif
2913
#endif
2914
 
2914
 
2915
	DBG(("%s: expired %d objects, %d bytes, idle? %d\n",
2915
	DBG(("%s: expired %d objects, %d bytes, idle? %d\n",
2916
	     __FUNCTION__, count, size, idle));
2916
	     __FUNCTION__, count, size, idle));
2917
 
2917
 
2918
	kgem->need_expire = !idle;
2918
	kgem->need_expire = !idle;
2919
	return !idle;
2919
	return !idle;
2920
	(void)count;
2920
	(void)count;
2921
	(void)size;
2921
	(void)size;
2922
}
2922
}
2923
 
2923
 
2924
void kgem_cleanup_cache(struct kgem *kgem)
2924
void kgem_cleanup_cache(struct kgem *kgem)
2925
{
2925
{
2926
	unsigned int i;
2926
	unsigned int i;
2927
	int n;
2927
	int n;
2928
 
2928
 
2929
	/* sync to the most recent request */
2929
	/* sync to the most recent request */
2930
	for (n = 0; n < ARRAY_SIZE(kgem->requests); n++) {
2930
	for (n = 0; n < ARRAY_SIZE(kgem->requests); n++) {
2931
		if (!list_is_empty(&kgem->requests[n])) {
2931
		if (!list_is_empty(&kgem->requests[n])) {
2932
			struct kgem_request *rq;
2932
			struct kgem_request *rq;
2933
			struct drm_i915_gem_set_domain set_domain;
2933
			struct drm_i915_gem_set_domain set_domain;
2934
 
2934
 
2935
			rq = list_first_entry(&kgem->requests[n],
2935
			rq = list_first_entry(&kgem->requests[n],
2936
					      struct kgem_request,
2936
					      struct kgem_request,
2937
					      list);
2937
					      list);
2938
 
2938
 
2939
			DBG(("%s: sync on cleanup\n", __FUNCTION__));
2939
			DBG(("%s: sync on cleanup\n", __FUNCTION__));
2940
 
2940
 
2941
			VG_CLEAR(set_domain);
2941
			VG_CLEAR(set_domain);
2942
			set_domain.handle = rq->bo->handle;
2942
			set_domain.handle = rq->bo->handle;
2943
			set_domain.read_domains = I915_GEM_DOMAIN_GTT;
2943
			set_domain.read_domains = I915_GEM_DOMAIN_GTT;
2944
			set_domain.write_domain = I915_GEM_DOMAIN_GTT;
2944
			set_domain.write_domain = I915_GEM_DOMAIN_GTT;
2945
			(void)drmIoctl(kgem->fd,
2945
			(void)drmIoctl(kgem->fd,
2946
				       DRM_IOCTL_I915_GEM_SET_DOMAIN,
2946
				       DRM_IOCTL_I915_GEM_SET_DOMAIN,
2947
				       &set_domain);
2947
				       &set_domain);
2948
		}
2948
		}
2949
	}
2949
	}
2950
 
2950
 
2951
	kgem_retire(kgem);
2951
	kgem_retire(kgem);
2952
	kgem_cleanup(kgem);
2952
	kgem_cleanup(kgem);
2953
 
2953
 
2954
	for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
2954
	for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
2955
		while (!list_is_empty(&kgem->inactive[i]))
2955
		while (!list_is_empty(&kgem->inactive[i]))
2956
			kgem_bo_free(kgem,
2956
			kgem_bo_free(kgem,
2957
				     list_last_entry(&kgem->inactive[i],
2957
				     list_last_entry(&kgem->inactive[i],
2958
						     struct kgem_bo, list));
2958
						     struct kgem_bo, list));
2959
	}
2959
	}
2960
 
2960
 
2961
	kgem_clean_large_cache(kgem);
2961
	kgem_clean_large_cache(kgem);
2962
 
2962
 
2963
	while (!list_is_empty(&kgem->snoop))
2963
	while (!list_is_empty(&kgem->snoop))
2964
		kgem_bo_free(kgem,
2964
		kgem_bo_free(kgem,
2965
			     list_last_entry(&kgem->snoop,
2965
			     list_last_entry(&kgem->snoop,
2966
					     struct kgem_bo, list));
2966
					     struct kgem_bo, list));
2967
 
2967
 
2968
	while (__kgem_freed_bo) {
2968
	while (__kgem_freed_bo) {
2969
		struct kgem_bo *bo = __kgem_freed_bo;
2969
		struct kgem_bo *bo = __kgem_freed_bo;
2970
		__kgem_freed_bo = *(struct kgem_bo **)bo;
2970
		__kgem_freed_bo = *(struct kgem_bo **)bo;
2971
		free(bo);
2971
		free(bo);
2972
	}
2972
	}
2973
 
2973
 
2974
	kgem->need_purge = false;
2974
	kgem->need_purge = false;
2975
	kgem->need_expire = false;
2975
	kgem->need_expire = false;
2976
}
2976
}
2977
 
2977
 
2978
static struct kgem_bo *
2978
static struct kgem_bo *
2979
search_linear_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags)
2979
search_linear_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags)
2980
{
2980
{
2981
	struct kgem_bo *bo, *first = NULL;
2981
	struct kgem_bo *bo, *first = NULL;
2982
	bool use_active = (flags & CREATE_INACTIVE) == 0;
2982
	bool use_active = (flags & CREATE_INACTIVE) == 0;
2983
	struct list *cache;
2983
	struct list *cache;
2984
 
2984
 
2985
	DBG(("%s: num_pages=%d, flags=%x, use_active? %d, use_large=%d [max=%d]\n",
2985
	DBG(("%s: num_pages=%d, flags=%x, use_active? %d, use_large=%d [max=%d]\n",
2986
	     __FUNCTION__, num_pages, flags, use_active,
2986
	     __FUNCTION__, num_pages, flags, use_active,
2987
	     num_pages >= MAX_CACHE_SIZE / PAGE_SIZE,
2987
	     num_pages >= MAX_CACHE_SIZE / PAGE_SIZE,
2988
	     MAX_CACHE_SIZE / PAGE_SIZE));
2988
	     MAX_CACHE_SIZE / PAGE_SIZE));
2989
 
2989
 
2990
	assert(num_pages);
2990
	assert(num_pages);
2991
 
2991
 
2992
	if (num_pages >= MAX_CACHE_SIZE / PAGE_SIZE) {
2992
	if (num_pages >= MAX_CACHE_SIZE / PAGE_SIZE) {
2993
		DBG(("%s: searching large buffers\n", __FUNCTION__));
2993
		DBG(("%s: searching large buffers\n", __FUNCTION__));
2994
retry_large:
2994
retry_large:
2995
		cache = use_active ? &kgem->large : &kgem->large_inactive;
2995
		cache = use_active ? &kgem->large : &kgem->large_inactive;
2996
		list_for_each_entry_safe(bo, first, cache, list) {
2996
		list_for_each_entry_safe(bo, first, cache, list) {
2997
			assert(bo->refcnt == 0);
2997
			assert(bo->refcnt == 0);
2998
			assert(bo->reusable);
2998
			assert(bo->reusable);
2999
			assert(!bo->scanout);
2999
			assert(!bo->scanout);
3000
 
3000
 
3001
			if (num_pages > num_pages(bo))
3001
			if (num_pages > num_pages(bo))
3002
				goto discard;
3002
				goto discard;
3003
 
3003
 
3004
			if (bo->tiling != I915_TILING_NONE) {
3004
			if (bo->tiling != I915_TILING_NONE) {
3005
				if (use_active)
3005
				if (use_active)
3006
					goto discard;
3006
					goto discard;
3007
 
3007
 
3008
				if (!gem_set_tiling(kgem->fd, bo->handle,
3008
				if (!gem_set_tiling(kgem->fd, bo->handle,
3009
						    I915_TILING_NONE, 0))
3009
						    I915_TILING_NONE, 0))
3010
					goto discard;
3010
					goto discard;
3011
 
3011
 
3012
				bo->tiling = I915_TILING_NONE;
3012
				bo->tiling = I915_TILING_NONE;
3013
				bo->pitch = 0;
3013
				bo->pitch = 0;
3014
			}
3014
			}
3015
 
3015
 
3016
			if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo))
3016
			if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo))
3017
				goto discard;
3017
				goto discard;
3018
 
3018
 
3019
			list_del(&bo->list);
3019
			list_del(&bo->list);
3020
			if (bo->rq == (void *)kgem)
3020
			if (bo->rq == (void *)kgem)
3021
				list_del(&bo->request);
3021
				list_del(&bo->request);
3022
 
3022
 
3023
			bo->delta = 0;
3023
			bo->delta = 0;
3024
			assert_tiling(kgem, bo);
3024
			assert_tiling(kgem, bo);
3025
			return bo;
3025
			return bo;
3026
 
3026
 
3027
discard:
3027
discard:
3028
			if (!use_active)
3028
			if (!use_active)
3029
				kgem_bo_free(kgem, bo);
3029
				kgem_bo_free(kgem, bo);
3030
		}
3030
		}
3031
 
3031
 
3032
		if (use_active) {
3032
		if (use_active) {
3033
			use_active = false;
3033
			use_active = false;
3034
			goto retry_large;
3034
			goto retry_large;
3035
		}
3035
		}
3036
 
3036
 
3037
		if (__kgem_throttle_retire(kgem, flags))
3037
		if (__kgem_throttle_retire(kgem, flags))
3038
			goto retry_large;
3038
			goto retry_large;
3039
 
3039
 
3040
		return NULL;
3040
		return NULL;
3041
	}
3041
	}
3042
 
3042
 
3043
	if (!use_active && list_is_empty(inactive(kgem, num_pages))) {
3043
	if (!use_active && list_is_empty(inactive(kgem, num_pages))) {
3044
		DBG(("%s: inactive and cache bucket empty\n",
3044
		DBG(("%s: inactive and cache bucket empty\n",
3045
		     __FUNCTION__));
3045
		     __FUNCTION__));
3046
 
3046
 
3047
		if (flags & CREATE_NO_RETIRE) {
3047
		if (flags & CREATE_NO_RETIRE) {
3048
			DBG(("%s: can not retire\n", __FUNCTION__));
3048
			DBG(("%s: can not retire\n", __FUNCTION__));
3049
			return NULL;
3049
			return NULL;
3050
		}
3050
		}
3051
 
3051
 
3052
		if (list_is_empty(active(kgem, num_pages, I915_TILING_NONE))) {
3052
		if (list_is_empty(active(kgem, num_pages, I915_TILING_NONE))) {
3053
			DBG(("%s: active cache bucket empty\n", __FUNCTION__));
3053
			DBG(("%s: active cache bucket empty\n", __FUNCTION__));
3054
			return NULL;
3054
			return NULL;
3055
		}
3055
		}
3056
 
3056
 
3057
		if (!__kgem_throttle_retire(kgem, flags)) {
3057
		if (!__kgem_throttle_retire(kgem, flags)) {
3058
			DBG(("%s: nothing retired\n", __FUNCTION__));
3058
			DBG(("%s: nothing retired\n", __FUNCTION__));
3059
			return NULL;
3059
			return NULL;
3060
		}
3060
		}
3061
 
3061
 
3062
		if (list_is_empty(inactive(kgem, num_pages))) {
3062
		if (list_is_empty(inactive(kgem, num_pages))) {
3063
			DBG(("%s: active cache bucket still empty after retire\n",
3063
			DBG(("%s: active cache bucket still empty after retire\n",
3064
			     __FUNCTION__));
3064
			     __FUNCTION__));
3065
			return NULL;
3065
			return NULL;
3066
		}
3066
		}
3067
	}
3067
	}
3068
 
3068
 
3069
	if (!use_active && flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
3069
	if (!use_active && flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
3070
		int for_cpu = !!(flags & CREATE_CPU_MAP);
3070
		int for_cpu = !!(flags & CREATE_CPU_MAP);
3071
		DBG(("%s: searching for inactive %s map\n",
3071
		DBG(("%s: searching for inactive %s map\n",
3072
		     __FUNCTION__, for_cpu ? "cpu" : "gtt"));
3072
		     __FUNCTION__, for_cpu ? "cpu" : "gtt"));
3073
		cache = &kgem->vma[for_cpu].inactive[cache_bucket(num_pages)];
3073
		cache = &kgem->vma[for_cpu].inactive[cache_bucket(num_pages)];
3074
		list_for_each_entry(bo, cache, vma) {
3074
		list_for_each_entry(bo, cache, vma) {
3075
			assert(IS_CPU_MAP(bo->map) == for_cpu);
3075
			assert(IS_CPU_MAP(bo->map) == for_cpu);
3076
			assert(bucket(bo) == cache_bucket(num_pages));
3076
			assert(bucket(bo) == cache_bucket(num_pages));
3077
			assert(bo->proxy == NULL);
3077
			assert(bo->proxy == NULL);
3078
			assert(bo->rq == NULL);
3078
			assert(bo->rq == NULL);
3079
			assert(bo->exec == NULL);
3079
			assert(bo->exec == NULL);
3080
			assert(!bo->scanout);
3080
			assert(!bo->scanout);
3081
 
3081
 
3082
			if (num_pages > num_pages(bo)) {
3082
			if (num_pages > num_pages(bo)) {
3083
				DBG(("inactive too small: %d < %d\n",
3083
				DBG(("inactive too small: %d < %d\n",
3084
				     num_pages(bo), num_pages));
3084
				     num_pages(bo), num_pages));
3085
				continue;
3085
				continue;
3086
			}
3086
			}
3087
 
3087
 
3088
			if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
3088
			if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
3089
				kgem_bo_free(kgem, bo);
3089
				kgem_bo_free(kgem, bo);
3090
				break;
3090
				break;
3091
			}
3091
			}
3092
 
3092
 
3093
			if (I915_TILING_NONE != bo->tiling &&
3093
			if (I915_TILING_NONE != bo->tiling &&
3094
			    !gem_set_tiling(kgem->fd, bo->handle,
3094
			    !gem_set_tiling(kgem->fd, bo->handle,
3095
					    I915_TILING_NONE, 0))
3095
					    I915_TILING_NONE, 0))
3096
				continue;
3096
				continue;
3097
 
3097
 
3098
			kgem_bo_remove_from_inactive(kgem, bo);
3098
			kgem_bo_remove_from_inactive(kgem, bo);
3099
 
3099
 
3100
			bo->tiling = I915_TILING_NONE;
3100
			bo->tiling = I915_TILING_NONE;
3101
			bo->pitch = 0;
3101
			bo->pitch = 0;
3102
			bo->delta = 0;
3102
			bo->delta = 0;
3103
			DBG(("  %s: found handle=%d (num_pages=%d) in linear vma cache\n",
3103
			DBG(("  %s: found handle=%d (num_pages=%d) in linear vma cache\n",
3104
			     __FUNCTION__, bo->handle, num_pages(bo)));
3104
			     __FUNCTION__, bo->handle, num_pages(bo)));
3105
			assert(use_active || bo->domain != DOMAIN_GPU);
3105
			assert(use_active || bo->domain != DOMAIN_GPU);
3106
			assert(!bo->needs_flush);
3106
			assert(!bo->needs_flush);
3107
			assert_tiling(kgem, bo);
3107
			assert_tiling(kgem, bo);
3108
			ASSERT_MAYBE_IDLE(kgem, bo->handle, !use_active);
3108
			ASSERT_MAYBE_IDLE(kgem, bo->handle, !use_active);
3109
			return bo;
3109
			return bo;
3110
		}
3110
		}
3111
 
3111
 
3112
		if (flags & CREATE_EXACT)
3112
		if (flags & CREATE_EXACT)
3113
			return NULL;
3113
			return NULL;
3114
 
3114
 
3115
		if (flags & CREATE_CPU_MAP && !kgem->has_llc)
3115
		if (flags & CREATE_CPU_MAP && !kgem->has_llc)
3116
			return NULL;
3116
			return NULL;
3117
	}
3117
	}
3118
 
3118
 
3119
	cache = use_active ? active(kgem, num_pages, I915_TILING_NONE) : inactive(kgem, num_pages);
3119
	cache = use_active ? active(kgem, num_pages, I915_TILING_NONE) : inactive(kgem, num_pages);
3120
	list_for_each_entry(bo, cache, list) {
3120
	list_for_each_entry(bo, cache, list) {
3121
		assert(bo->refcnt == 0);
3121
		assert(bo->refcnt == 0);
3122
		assert(bo->reusable);
3122
		assert(bo->reusable);
3123
		assert(!!bo->rq == !!use_active);
3123
		assert(!!bo->rq == !!use_active);
3124
		assert(bo->proxy == NULL);
3124
		assert(bo->proxy == NULL);
3125
		assert(!bo->scanout);
3125
		assert(!bo->scanout);
3126
 
3126
 
3127
		if (num_pages > num_pages(bo))
3127
		if (num_pages > num_pages(bo))
3128
			continue;
3128
			continue;
3129
 
3129
 
3130
		if (use_active &&
3130
		if (use_active &&
3131
		    kgem->gen <= 040 &&
3131
		    kgem->gen <= 040 &&
3132
		    bo->tiling != I915_TILING_NONE)
3132
		    bo->tiling != I915_TILING_NONE)
3133
			continue;
3133
			continue;
3134
 
3134
 
3135
		if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
3135
		if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
3136
			kgem_bo_free(kgem, bo);
3136
			kgem_bo_free(kgem, bo);
3137
			break;
3137
			break;
3138
		}
3138
		}
3139
 
3139
 
3140
		if (I915_TILING_NONE != bo->tiling) {
3140
		if (I915_TILING_NONE != bo->tiling) {
3141
			if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP))
3141
			if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP))
3142
				continue;
3142
				continue;
3143
 
3143
 
3144
			if (first)
3144
			if (first)
3145
				continue;
3145
				continue;
3146
 
3146
 
3147
			if (!gem_set_tiling(kgem->fd, bo->handle,
3147
			if (!gem_set_tiling(kgem->fd, bo->handle,
3148
					    I915_TILING_NONE, 0))
3148
					    I915_TILING_NONE, 0))
3149
				continue;
3149
				continue;
3150
 
3150
 
3151
			bo->tiling = I915_TILING_NONE;
3151
			bo->tiling = I915_TILING_NONE;
3152
			bo->pitch = 0;
3152
			bo->pitch = 0;
3153
		}
3153
		}
3154
 
3154
 
3155
		if (bo->map) {
3155
		if (bo->map) {
3156
			if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
3156
			if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
3157
				int for_cpu = !!(flags & CREATE_CPU_MAP);
3157
				int for_cpu = !!(flags & CREATE_CPU_MAP);
3158
				if (IS_CPU_MAP(bo->map) != for_cpu) {
3158
				if (IS_CPU_MAP(bo->map) != for_cpu) {
3159
					if (first != NULL)
3159
					if (first != NULL)
3160
						break;
3160
						break;
3161
 
3161
 
3162
					first = bo;
3162
					first = bo;
3163
					continue;
3163
					continue;
3164
				}
3164
				}
3165
			} else {
3165
			} else {
3166
				if (first != NULL)
3166
				if (first != NULL)
3167
					break;
3167
					break;
3168
 
3168
 
3169
				first = bo;
3169
				first = bo;
3170
				continue;
3170
				continue;
3171
			}
3171
			}
3172
		} else {
3172
		} else {
3173
			if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
3173
			if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
3174
				if (first != NULL)
3174
				if (first != NULL)
3175
					break;
3175
					break;
3176
 
3176
 
3177
				first = bo;
3177
				first = bo;
3178
				continue;
3178
				continue;
3179
			}
3179
			}
3180
		}
3180
		}
3181
 
3181
 
3182
		if (use_active)
3182
		if (use_active)
3183
			kgem_bo_remove_from_active(kgem, bo);
3183
			kgem_bo_remove_from_active(kgem, bo);
3184
		else
3184
		else
3185
			kgem_bo_remove_from_inactive(kgem, bo);
3185
			kgem_bo_remove_from_inactive(kgem, bo);
3186
 
3186
 
3187
		assert(bo->tiling == I915_TILING_NONE);
3187
		assert(bo->tiling == I915_TILING_NONE);
3188
		bo->pitch = 0;
3188
		bo->pitch = 0;
3189
		bo->delta = 0;
3189
		bo->delta = 0;
3190
		DBG(("  %s: found handle=%d (num_pages=%d) in linear %s cache\n",
3190
		DBG(("  %s: found handle=%d (num_pages=%d) in linear %s cache\n",
3191
		     __FUNCTION__, bo->handle, num_pages(bo),
3191
		     __FUNCTION__, bo->handle, num_pages(bo),
3192
		     use_active ? "active" : "inactive"));
3192
		     use_active ? "active" : "inactive"));
3193
		assert(list_is_empty(&bo->list));
3193
		assert(list_is_empty(&bo->list));
3194
		assert(use_active || bo->domain != DOMAIN_GPU);
3194
		assert(use_active || bo->domain != DOMAIN_GPU);
3195
		assert(!bo->needs_flush || use_active);
3195
		assert(!bo->needs_flush || use_active);
3196
		assert_tiling(kgem, bo);
3196
		assert_tiling(kgem, bo);
3197
		ASSERT_MAYBE_IDLE(kgem, bo->handle, !use_active);
3197
		ASSERT_MAYBE_IDLE(kgem, bo->handle, !use_active);
3198
		return bo;
3198
		return bo;
3199
	}
3199
	}
3200
 
3200
 
3201
	if (first) {
3201
	if (first) {
3202
		assert(first->tiling == I915_TILING_NONE);
3202
		assert(first->tiling == I915_TILING_NONE);
3203
 
3203
 
3204
		if (use_active)
3204
		if (use_active)
3205
			kgem_bo_remove_from_active(kgem, first);
3205
			kgem_bo_remove_from_active(kgem, first);
3206
		else
3206
		else
3207
			kgem_bo_remove_from_inactive(kgem, first);
3207
			kgem_bo_remove_from_inactive(kgem, first);
3208
 
3208
 
3209
		first->pitch = 0;
3209
		first->pitch = 0;
3210
		first->delta = 0;
3210
		first->delta = 0;
3211
		DBG(("  %s: found handle=%d (near-miss) (num_pages=%d) in linear %s cache\n",
3211
		DBG(("  %s: found handle=%d (near-miss) (num_pages=%d) in linear %s cache\n",
3212
		     __FUNCTION__, first->handle, num_pages(first),
3212
		     __FUNCTION__, first->handle, num_pages(first),
3213
		     use_active ? "active" : "inactive"));
3213
		     use_active ? "active" : "inactive"));
3214
		assert(list_is_empty(&first->list));
3214
		assert(list_is_empty(&first->list));
3215
		assert(use_active || first->domain != DOMAIN_GPU);
3215
		assert(use_active || first->domain != DOMAIN_GPU);
3216
		assert(!first->needs_flush || use_active);
3216
		assert(!first->needs_flush || use_active);
3217
		ASSERT_MAYBE_IDLE(kgem, first->handle, !use_active);
3217
		ASSERT_MAYBE_IDLE(kgem, first->handle, !use_active);
3218
		return first;
3218
		return first;
3219
	}
3219
	}
3220
 
3220
 
3221
	return NULL;
3221
	return NULL;
3222
}
3222
}
3223
 
3223
 
3224
 
3224
 
3225
struct kgem_bo *kgem_create_linear(struct kgem *kgem, int size, unsigned flags)
3225
struct kgem_bo *kgem_create_linear(struct kgem *kgem, int size, unsigned flags)
3226
{
3226
{
3227
	struct kgem_bo *bo;
3227
	struct kgem_bo *bo;
3228
	uint32_t handle;
3228
	uint32_t handle;
3229
 
3229
 
3230
	DBG(("%s(%d)\n", __FUNCTION__, size));
3230
	DBG(("%s(%d)\n", __FUNCTION__, size));
3231
	assert(size);
3231
	assert(size);
3232
 
3232
 
3233
	if (flags & CREATE_GTT_MAP && kgem->has_llc) {
3233
	if (flags & CREATE_GTT_MAP && kgem->has_llc) {
3234
		flags &= ~CREATE_GTT_MAP;
3234
		flags &= ~CREATE_GTT_MAP;
3235
		flags |= CREATE_CPU_MAP;
3235
		flags |= CREATE_CPU_MAP;
3236
	}
3236
	}
3237
 
3237
 
3238
	size = NUM_PAGES(size);
3238
	size = NUM_PAGES(size);
3239
	bo = search_linear_cache(kgem, size, CREATE_INACTIVE | flags);
3239
	bo = search_linear_cache(kgem, size, CREATE_INACTIVE | flags);
3240
	if (bo) {
3240
	if (bo) {
3241
		assert(bo->domain != DOMAIN_GPU);
3241
		assert(bo->domain != DOMAIN_GPU);
3242
		ASSERT_IDLE(kgem, bo->handle);
3242
		ASSERT_IDLE(kgem, bo->handle);
3243
		bo->refcnt = 1;
3243
		bo->refcnt = 1;
3244
		return bo;
3244
		return bo;
3245
	}
3245
	}
3246
 
3246
 
3247
	if (flags & CREATE_CACHED)
3247
	if (flags & CREATE_CACHED)
3248
		return NULL;
3248
		return NULL;
3249
 
3249
 
3250
	handle = gem_create(kgem->fd, size);
3250
	handle = gem_create(kgem->fd, size);
3251
	if (handle == 0)
3251
	if (handle == 0)
3252
		return NULL;
3252
		return NULL;
3253
 
3253
 
3254
	DBG(("%s: new handle=%d, num_pages=%d\n", __FUNCTION__, handle, size));
3254
	DBG(("%s: new handle=%d, num_pages=%d\n", __FUNCTION__, handle, size));
3255
	bo = __kgem_bo_alloc(handle, size);
3255
	bo = __kgem_bo_alloc(handle, size);
3256
	if (bo == NULL) {
3256
	if (bo == NULL) {
3257
		gem_close(kgem->fd, handle);
3257
		gem_close(kgem->fd, handle);
3258
		return NULL;
3258
		return NULL;
3259
	}
3259
	}
3260
 
3260
 
3261
	debug_alloc__bo(kgem, bo);
3261
	debug_alloc__bo(kgem, bo);
3262
	return bo;
3262
	return bo;
3263
}
3263
}
3264
 
3264
 
3265
inline int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo)
3265
inline int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo)
3266
{
3266
{
3267
	unsigned int size;
3267
	unsigned int size;
3268
 
3268
 
3269
	assert(bo->tiling);
3269
	assert(bo->tiling);
3270
	assert_tiling(kgem, bo);
3270
	assert_tiling(kgem, bo);
3271
	assert(kgem->gen < 040);
3271
	assert(kgem->gen < 040);
3272
 
3272
 
3273
	if (kgem->gen < 030)
3273
	if (kgem->gen < 030)
3274
		size = 512 * 1024;
3274
		size = 512 * 1024;
3275
	else
3275
	else
3276
		size = 1024 * 1024;
3276
		size = 1024 * 1024;
3277
	while (size < bytes(bo))
3277
	while (size < bytes(bo))
3278
		size *= 2;
3278
		size *= 2;
3279
 
3279
 
3280
	return size;
3280
	return size;
3281
}
3281
}
3282
 
3282
 
3283
struct kgem_bo *kgem_create_2d(struct kgem *kgem,
3283
struct kgem_bo *kgem_create_2d(struct kgem *kgem,
3284
			       int width,
3284
			       int width,
3285
			       int height,
3285
			       int height,
3286
			       int bpp,
3286
			       int bpp,
3287
			       int tiling,
3287
			       int tiling,
3288
			       uint32_t flags)
3288
			       uint32_t flags)
3289
{
3289
{
3290
	struct list *cache;
3290
	struct list *cache;
3291
	struct kgem_bo *bo;
3291
	struct kgem_bo *bo;
3292
	uint32_t pitch, tiled_height, size;
3292
	uint32_t pitch, tiled_height, size;
3293
	uint32_t handle;
3293
	uint32_t handle;
3294
	int i, bucket, retry;
3294
	int i, bucket, retry;
3295
	bool exact = flags & (CREATE_EXACT | CREATE_SCANOUT);
3295
	bool exact = flags & (CREATE_EXACT | CREATE_SCANOUT);
3296
 
3296
 
3297
	if (tiling < 0)
3297
	if (tiling < 0)
3298
		exact = true, tiling = -tiling;
3298
		exact = true, tiling = -tiling;
3299
 
3299
 
3300
 
3300
 
3301
	DBG(("%s(%dx%d, bpp=%d, tiling=%d, exact=%d, inactive=%d, cpu-mapping=%d, gtt-mapping=%d, scanout?=%d, prime?=%d, temp?=%d)\n", __FUNCTION__,
3301
	DBG(("%s(%dx%d, bpp=%d, tiling=%d, exact=%d, inactive=%d, cpu-mapping=%d, gtt-mapping=%d, scanout?=%d, prime?=%d, temp?=%d)\n", __FUNCTION__,
3302
	     width, height, bpp, tiling, exact,
3302
	     width, height, bpp, tiling, exact,
3303
	     !!(flags & CREATE_INACTIVE),
3303
	     !!(flags & CREATE_INACTIVE),
3304
	     !!(flags & CREATE_CPU_MAP),
3304
	     !!(flags & CREATE_CPU_MAP),
3305
	     !!(flags & CREATE_GTT_MAP),
3305
	     !!(flags & CREATE_GTT_MAP),
3306
	     !!(flags & CREATE_SCANOUT),
3306
	     !!(flags & CREATE_SCANOUT),
3307
	     !!(flags & CREATE_PRIME),
3307
	     !!(flags & CREATE_PRIME),
3308
	     !!(flags & CREATE_TEMPORARY)));
3308
	     !!(flags & CREATE_TEMPORARY)));
3309
 
3309
 
3310
	size = kgem_surface_size(kgem, kgem->has_relaxed_fencing, flags,
3310
	size = kgem_surface_size(kgem, kgem->has_relaxed_fencing, flags,
3311
				 width, height, bpp, tiling, &pitch);
3311
				 width, height, bpp, tiling, &pitch);
3312
	assert(size && size <= kgem->max_object_size);
3312
	assert(size && size <= kgem->max_object_size);
3313
	size /= PAGE_SIZE;
3313
	size /= PAGE_SIZE;
3314
	bucket = cache_bucket(size);
3314
	bucket = cache_bucket(size);
3315
 
3315
 
3316
	if (flags & CREATE_SCANOUT) {
3316
	if (flags & CREATE_SCANOUT) {
3317
		struct kgem_bo *last = NULL;
3317
		struct kgem_bo *last = NULL;
3318
 
3318
 
3319
		list_for_each_entry_reverse(bo, &kgem->scanout, list) {
3319
		list_for_each_entry_reverse(bo, &kgem->scanout, list) {
3320
			assert(bo->scanout);
3320
			assert(bo->scanout);
3321
			assert(bo->delta);
3321
			assert(bo->delta);
3322
			assert(!bo->flush);
3322
			assert(!bo->flush);
3323
			assert_tiling(kgem, bo);
3323
			assert_tiling(kgem, bo);
3324
 
3324
 
3325
			if (size > num_pages(bo) || num_pages(bo) > 2*size)
3325
			if (size > num_pages(bo) || num_pages(bo) > 2*size)
3326
				continue;
3326
				continue;
3327
 
3327
 
3328
			if (bo->tiling != tiling ||
3328
			if (bo->tiling != tiling ||
3329
			    (tiling != I915_TILING_NONE && bo->pitch != pitch)) {
3329
			    (tiling != I915_TILING_NONE && bo->pitch != pitch)) {
3330
				if (!gem_set_tiling(kgem->fd, bo->handle,
3330
				if (!gem_set_tiling(kgem->fd, bo->handle,
3331
						    tiling, pitch))
3331
						    tiling, pitch))
3332
					continue;
3332
					continue;
3333
 
3333
 
3334
				bo->tiling = tiling;
3334
				bo->tiling = tiling;
3335
				bo->pitch = pitch;
3335
				bo->pitch = pitch;
3336
			}
3336
			}
3337
 
3337
 
3338
			if (flags & CREATE_INACTIVE && bo->rq) {
3338
			if (flags & CREATE_INACTIVE && bo->rq) {
3339
				last = bo;
3339
				last = bo;
3340
				continue;
3340
				continue;
3341
			}
3341
			}
3342
 
3342
 
3343
			list_del(&bo->list);
3343
			list_del(&bo->list);
3344
 
3344
 
3345
			bo->unique_id = kgem_get_unique_id(kgem);
3345
			bo->unique_id = kgem_get_unique_id(kgem);
3346
			DBG(("  1:from scanout: pitch=%d, tiling=%d, handle=%d, id=%d\n",
3346
			DBG(("  1:from scanout: pitch=%d, tiling=%d, handle=%d, id=%d\n",
3347
			     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
3347
			     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
3348
			assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
3348
			assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
3349
			assert_tiling(kgem, bo);
3349
			assert_tiling(kgem, bo);
3350
			bo->refcnt = 1;
3350
			bo->refcnt = 1;
3351
			return bo;
3351
			return bo;
3352
		}
3352
		}
3353
 
3353
 
3354
		if (last) {
3354
		if (last) {
3355
			list_del(&last->list);
3355
			list_del(&last->list);
3356
 
3356
 
3357
			last->unique_id = kgem_get_unique_id(kgem);
3357
			last->unique_id = kgem_get_unique_id(kgem);
3358
			DBG(("  1:from scanout: pitch=%d, tiling=%d, handle=%d, id=%d\n",
3358
			DBG(("  1:from scanout: pitch=%d, tiling=%d, handle=%d, id=%d\n",
3359
			     last->pitch, last->tiling, last->handle, last->unique_id));
3359
			     last->pitch, last->tiling, last->handle, last->unique_id));
3360
			assert(last->pitch*kgem_aligned_height(kgem, height, last->tiling) <= kgem_bo_size(last));
3360
			assert(last->pitch*kgem_aligned_height(kgem, height, last->tiling) <= kgem_bo_size(last));
3361
			assert_tiling(kgem, last);
3361
			assert_tiling(kgem, last);
3362
			last->refcnt = 1;
3362
			last->refcnt = 1;
3363
			return last;
3363
			return last;
3364
		}
3364
		}
3365
 
3365
 
3366
		bo = NULL; //__kgem_bo_create_as_display(kgem, size, tiling, pitch);
3366
		bo = NULL; //__kgem_bo_create_as_display(kgem, size, tiling, pitch);
3367
		if (bo)
3367
		if (bo)
3368
			return bo;
3368
			return bo;
3369
	}
3369
	}
3370
 
3370
 
3371
	if (bucket >= NUM_CACHE_BUCKETS) {
3371
	if (bucket >= NUM_CACHE_BUCKETS) {
3372
		DBG(("%s: large bo num pages=%d, bucket=%d\n",
3372
		DBG(("%s: large bo num pages=%d, bucket=%d\n",
3373
		     __FUNCTION__, size, bucket));
3373
		     __FUNCTION__, size, bucket));
3374
 
3374
 
3375
		if (flags & CREATE_INACTIVE)
3375
		if (flags & CREATE_INACTIVE)
3376
			goto large_inactive;
3376
			goto large_inactive;
3377
 
3377
 
3378
		tiled_height = kgem_aligned_height(kgem, height, tiling);
3378
		tiled_height = kgem_aligned_height(kgem, height, tiling);
3379
 
3379
 
3380
		list_for_each_entry(bo, &kgem->large, list) {
3380
		list_for_each_entry(bo, &kgem->large, list) {
3381
			assert(!bo->purged);
3381
			assert(!bo->purged);
3382
			assert(!bo->scanout);
3382
			assert(!bo->scanout);
3383
			assert(bo->refcnt == 0);
3383
			assert(bo->refcnt == 0);
3384
			assert(bo->reusable);
3384
			assert(bo->reusable);
3385
			assert_tiling(kgem, bo);
3385
			assert_tiling(kgem, bo);
3386
 
3386
 
3387
			if (kgem->gen < 040) {
3387
			if (kgem->gen < 040) {
3388
				if (bo->pitch < pitch) {
3388
				if (bo->pitch < pitch) {
3389
					DBG(("tiled and pitch too small: tiling=%d, (want %d), pitch=%d, need %d\n",
3389
					DBG(("tiled and pitch too small: tiling=%d, (want %d), pitch=%d, need %d\n",
3390
					     bo->tiling, tiling,
3390
					     bo->tiling, tiling,
3391
					     bo->pitch, pitch));
3391
					     bo->pitch, pitch));
3392
					continue;
3392
					continue;
3393
				}
3393
				}
3394
 
3394
 
3395
				if (bo->pitch * tiled_height > bytes(bo))
3395
				if (bo->pitch * tiled_height > bytes(bo))
3396
					continue;
3396
					continue;
3397
			} else {
3397
			} else {
3398
				if (num_pages(bo) < size)
3398
				if (num_pages(bo) < size)
3399
					continue;
3399
					continue;
3400
 
3400
 
3401
				if (bo->pitch != pitch || bo->tiling != tiling) {
3401
				if (bo->pitch != pitch || bo->tiling != tiling) {
3402
					if (!gem_set_tiling(kgem->fd, bo->handle,
3402
					if (!gem_set_tiling(kgem->fd, bo->handle,
3403
							    tiling, pitch))
3403
							    tiling, pitch))
3404
						continue;
3404
						continue;
3405
 
3405
 
3406
					bo->pitch = pitch;
3406
					bo->pitch = pitch;
3407
					bo->tiling = tiling;
3407
					bo->tiling = tiling;
3408
				}
3408
				}
3409
			}
3409
			}
3410
 
3410
 
3411
			kgem_bo_remove_from_active(kgem, bo);
3411
			kgem_bo_remove_from_active(kgem, bo);
3412
 
3412
 
3413
			bo->unique_id = kgem_get_unique_id(kgem);
3413
			bo->unique_id = kgem_get_unique_id(kgem);
3414
			bo->delta = 0;
3414
			bo->delta = 0;
3415
			DBG(("  1:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n",
3415
			DBG(("  1:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n",
3416
			     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
3416
			     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
3417
			assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
3417
			assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
3418
			assert_tiling(kgem, bo);
3418
			assert_tiling(kgem, bo);
3419
			bo->refcnt = 1;
3419
			bo->refcnt = 1;
3420
			bo->flush = true;
3420
			bo->flush = true;
3421
			return bo;
3421
			return bo;
3422
		}
3422
		}
3423
 
3423
 
3424
large_inactive:
3424
large_inactive:
3425
		__kgem_throttle_retire(kgem, flags);
3425
		__kgem_throttle_retire(kgem, flags);
3426
		list_for_each_entry(bo, &kgem->large_inactive, list) {
3426
		list_for_each_entry(bo, &kgem->large_inactive, list) {
3427
			assert(bo->refcnt == 0);
3427
			assert(bo->refcnt == 0);
3428
			assert(bo->reusable);
3428
			assert(bo->reusable);
3429
			assert(!bo->scanout);
3429
			assert(!bo->scanout);
3430
			assert_tiling(kgem, bo);
3430
			assert_tiling(kgem, bo);
3431
 
3431
 
3432
			if (size > num_pages(bo))
3432
			if (size > num_pages(bo))
3433
				continue;
3433
				continue;
3434
 
3434
 
3435
			if (bo->tiling != tiling ||
3435
			if (bo->tiling != tiling ||
3436
			    (tiling != I915_TILING_NONE && bo->pitch != pitch)) {
3436
			    (tiling != I915_TILING_NONE && bo->pitch != pitch)) {
3437
				if (!gem_set_tiling(kgem->fd, bo->handle,
3437
				if (!gem_set_tiling(kgem->fd, bo->handle,
3438
						    tiling, pitch))
3438
						    tiling, pitch))
3439
					continue;
3439
					continue;
3440
 
3440
 
3441
				bo->tiling = tiling;
3441
				bo->tiling = tiling;
3442
				bo->pitch = pitch;
3442
				bo->pitch = pitch;
3443
			}
3443
			}
3444
 
3444
 
3445
			if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
3445
			if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
3446
				kgem_bo_free(kgem, bo);
3446
				kgem_bo_free(kgem, bo);
3447
				break;
3447
				break;
3448
			}
3448
			}
3449
 
3449
 
3450
			list_del(&bo->list);
3450
			list_del(&bo->list);
3451
 
3451
 
3452
			assert(bo->domain != DOMAIN_GPU);
3452
			assert(bo->domain != DOMAIN_GPU);
3453
			bo->unique_id = kgem_get_unique_id(kgem);
3453
			bo->unique_id = kgem_get_unique_id(kgem);
3454
			bo->pitch = pitch;
3454
			bo->pitch = pitch;
3455
			bo->delta = 0;
3455
			bo->delta = 0;
3456
			DBG(("  1:from large inactive: pitch=%d, tiling=%d, handle=%d, id=%d\n",
3456
			DBG(("  1:from large inactive: pitch=%d, tiling=%d, handle=%d, id=%d\n",
3457
			     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
3457
			     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
3458
			assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
3458
			assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
3459
			assert_tiling(kgem, bo);
3459
			assert_tiling(kgem, bo);
3460
			bo->refcnt = 1;
3460
			bo->refcnt = 1;
3461
			return bo;
3461
			return bo;
3462
		}
3462
		}
3463
 
3463
 
3464
		goto create;
3464
		goto create;
3465
	}
3465
	}
3466
 
3466
 
3467
	if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
3467
	if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
3468
		int for_cpu = !!(flags & CREATE_CPU_MAP);
3468
		int for_cpu = !!(flags & CREATE_CPU_MAP);
3469
		if (kgem->has_llc && tiling == I915_TILING_NONE)
3469
		if (kgem->has_llc && tiling == I915_TILING_NONE)
3470
			for_cpu = 1;
3470
			for_cpu = 1;
3471
		/* We presume that we will need to upload to this bo,
3471
		/* We presume that we will need to upload to this bo,
3472
		 * and so would prefer to have an active VMA.
3472
		 * and so would prefer to have an active VMA.
3473
		 */
3473
		 */
3474
		cache = &kgem->vma[for_cpu].inactive[bucket];
3474
		cache = &kgem->vma[for_cpu].inactive[bucket];
3475
		do {
3475
		do {
3476
			list_for_each_entry(bo, cache, vma) {
3476
			list_for_each_entry(bo, cache, vma) {
3477
				assert(bucket(bo) == bucket);
3477
				assert(bucket(bo) == bucket);
3478
				assert(bo->refcnt == 0);
3478
				assert(bo->refcnt == 0);
3479
				assert(!bo->scanout);
3479
				assert(!bo->scanout);
3480
				assert(bo->map);
3480
				assert(bo->map);
3481
				assert(IS_CPU_MAP(bo->map) == for_cpu);
3481
				assert(IS_CPU_MAP(bo->map) == for_cpu);
3482
				assert(bo->rq == NULL);
3482
				assert(bo->rq == NULL);
3483
				assert(list_is_empty(&bo->request));
3483
				assert(list_is_empty(&bo->request));
3484
				assert(bo->flush == false);
3484
				assert(bo->flush == false);
3485
				assert_tiling(kgem, bo);
3485
				assert_tiling(kgem, bo);
3486
 
3486
 
3487
				if (size > num_pages(bo)) {
3487
				if (size > num_pages(bo)) {
3488
					DBG(("inactive too small: %d < %d\n",
3488
					DBG(("inactive too small: %d < %d\n",
3489
					     num_pages(bo), size));
3489
					     num_pages(bo), size));
3490
					continue;
3490
					continue;
3491
				}
3491
				}
3492
 
3492
 
3493
				if (bo->tiling != tiling ||
3493
				if (bo->tiling != tiling ||
3494
				    (tiling != I915_TILING_NONE && bo->pitch != pitch)) {
3494
				    (tiling != I915_TILING_NONE && bo->pitch != pitch)) {
3495
					DBG(("inactive vma with wrong tiling: %d < %d\n",
3495
					DBG(("inactive vma with wrong tiling: %d < %d\n",
3496
					     bo->tiling, tiling));
3496
					     bo->tiling, tiling));
3497
					continue;
3497
					continue;
3498
				}
3498
				}
3499
 
3499
 
3500
				if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
3500
				if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
3501
					kgem_bo_free(kgem, bo);
3501
					kgem_bo_free(kgem, bo);
3502
					break;
3502
					break;
3503
				}
3503
				}
3504
 
3504
 
3505
				assert(bo->tiling == tiling);
3505
				assert(bo->tiling == tiling);
3506
				bo->pitch = pitch;
3506
				bo->pitch = pitch;
3507
				bo->delta = 0;
3507
				bo->delta = 0;
3508
				bo->unique_id = kgem_get_unique_id(kgem);
3508
				bo->unique_id = kgem_get_unique_id(kgem);
3509
				bo->domain = DOMAIN_NONE;
3509
				bo->domain = DOMAIN_NONE;
3510
 
3510
 
3511
				kgem_bo_remove_from_inactive(kgem, bo);
3511
				kgem_bo_remove_from_inactive(kgem, bo);
3512
 
3512
 
3513
				DBG(("  from inactive vma: pitch=%d, tiling=%d: handle=%d, id=%d\n",
3513
				DBG(("  from inactive vma: pitch=%d, tiling=%d: handle=%d, id=%d\n",
3514
				     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
3514
				     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
3515
				assert(bo->reusable);
3515
				assert(bo->reusable);
3516
				assert(bo->domain != DOMAIN_GPU);
3516
				assert(bo->domain != DOMAIN_GPU);
3517
				ASSERT_IDLE(kgem, bo->handle);
3517
				ASSERT_IDLE(kgem, bo->handle);
3518
				assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
3518
				assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
3519
				assert_tiling(kgem, bo);
3519
				assert_tiling(kgem, bo);
3520
				bo->refcnt = 1;
3520
				bo->refcnt = 1;
3521
				return bo;
3521
				return bo;
3522
			}
3522
			}
3523
		} while (!list_is_empty(cache) &&
3523
		} while (!list_is_empty(cache) &&
3524
			 __kgem_throttle_retire(kgem, flags));
3524
			 __kgem_throttle_retire(kgem, flags));
3525
 
3525
 
3526
		if (flags & CREATE_CPU_MAP && !kgem->has_llc) {
3526
		if (flags & CREATE_CPU_MAP && !kgem->has_llc) {
3527
			if (list_is_empty(&kgem->active[bucket][tiling]) &&
3527
			if (list_is_empty(&kgem->active[bucket][tiling]) &&
3528
			    list_is_empty(&kgem->inactive[bucket]))
3528
			    list_is_empty(&kgem->inactive[bucket]))
3529
				flags &= ~CREATE_CACHED;
3529
				flags &= ~CREATE_CACHED;
3530
 
3530
 
3531
			goto create;
3531
			goto create;
3532
	}
3532
	}
3533
	}
3533
	}
3534
 
3534
 
3535
	if (flags & CREATE_INACTIVE)
3535
	if (flags & CREATE_INACTIVE)
3536
		goto skip_active_search;
3536
		goto skip_active_search;
3537
 
3537
 
3538
	/* Best active match */
3538
	/* Best active match */
3539
	retry = NUM_CACHE_BUCKETS - bucket;
3539
	retry = NUM_CACHE_BUCKETS - bucket;
3540
	if (retry > 3 && (flags & CREATE_TEMPORARY) == 0)
3540
	if (retry > 3 && (flags & CREATE_TEMPORARY) == 0)
3541
		retry = 3;
3541
		retry = 3;
3542
search_again:
3542
search_again:
3543
	assert(bucket < NUM_CACHE_BUCKETS);
3543
	assert(bucket < NUM_CACHE_BUCKETS);
3544
	cache = &kgem->active[bucket][tiling];
3544
	cache = &kgem->active[bucket][tiling];
3545
	if (tiling) {
3545
	if (tiling) {
3546
		tiled_height = kgem_aligned_height(kgem, height, tiling);
3546
		tiled_height = kgem_aligned_height(kgem, height, tiling);
3547
		list_for_each_entry(bo, cache, list) {
3547
		list_for_each_entry(bo, cache, list) {
3548
			assert(!bo->purged);
3548
			assert(!bo->purged);
3549
			assert(bo->refcnt == 0);
3549
			assert(bo->refcnt == 0);
3550
			assert(bucket(bo) == bucket);
3550
			assert(bucket(bo) == bucket);
3551
			assert(bo->reusable);
3551
			assert(bo->reusable);
3552
			assert(bo->tiling == tiling);
3552
			assert(bo->tiling == tiling);
3553
			assert(bo->flush == false);
3553
			assert(bo->flush == false);
3554
			assert(!bo->scanout);
3554
			assert(!bo->scanout);
3555
			assert_tiling(kgem, bo);
3555
			assert_tiling(kgem, bo);
3556
 
3556
 
3557
			if (kgem->gen < 040) {
3557
			if (kgem->gen < 040) {
3558
				if (bo->pitch < pitch) {
3558
				if (bo->pitch < pitch) {
3559
					DBG(("tiled and pitch too small: tiling=%d, (want %d), pitch=%d, need %d\n",
3559
					DBG(("tiled and pitch too small: tiling=%d, (want %d), pitch=%d, need %d\n",
3560
					     bo->tiling, tiling,
3560
					     bo->tiling, tiling,
3561
					     bo->pitch, pitch));
3561
					     bo->pitch, pitch));
3562
					continue;
3562
					continue;
3563
				}
3563
				}
3564
 
3564
 
3565
				if (bo->pitch * tiled_height > bytes(bo))
3565
				if (bo->pitch * tiled_height > bytes(bo))
3566
					continue;
3566
					continue;
3567
			} else {
3567
			} else {
3568
				if (num_pages(bo) < size)
3568
				if (num_pages(bo) < size)
3569
					continue;
3569
					continue;
3570
 
3570
 
3571
				if (bo->pitch != pitch) {
3571
				if (bo->pitch != pitch) {
3572
					if (!gem_set_tiling(kgem->fd,
3572
					if (!gem_set_tiling(kgem->fd,
3573
							    bo->handle,
3573
							    bo->handle,
3574
							    tiling, pitch))
3574
							    tiling, pitch))
3575
						continue;
3575
						continue;
3576
 
3576
 
3577
					bo->pitch = pitch;
3577
					bo->pitch = pitch;
3578
				}
3578
				}
3579
			}
3579
			}
3580
 
3580
 
3581
			kgem_bo_remove_from_active(kgem, bo);
3581
			kgem_bo_remove_from_active(kgem, bo);
3582
 
3582
 
3583
			bo->unique_id = kgem_get_unique_id(kgem);
3583
			bo->unique_id = kgem_get_unique_id(kgem);
3584
			bo->delta = 0;
3584
			bo->delta = 0;
3585
			DBG(("  1:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n",
3585
			DBG(("  1:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n",
3586
			     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
3586
			     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
3587
			assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
3587
			assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
3588
			assert_tiling(kgem, bo);
3588
			assert_tiling(kgem, bo);
3589
			bo->refcnt = 1;
3589
			bo->refcnt = 1;
3590
			return bo;
3590
			return bo;
3591
		}
3591
		}
3592
	} else {
3592
	} else {
3593
		list_for_each_entry(bo, cache, list) {
3593
		list_for_each_entry(bo, cache, list) {
3594
			assert(bucket(bo) == bucket);
3594
			assert(bucket(bo) == bucket);
3595
			assert(!bo->purged);
3595
			assert(!bo->purged);
3596
			assert(bo->refcnt == 0);
3596
			assert(bo->refcnt == 0);
3597
			assert(bo->reusable);
3597
			assert(bo->reusable);
3598
			assert(!bo->scanout);
3598
			assert(!bo->scanout);
3599
			assert(bo->tiling == tiling);
3599
			assert(bo->tiling == tiling);
3600
			assert(bo->flush == false);
3600
			assert(bo->flush == false);
3601
			assert_tiling(kgem, bo);
3601
			assert_tiling(kgem, bo);
3602
 
3602
 
3603
			if (num_pages(bo) < size)
3603
			if (num_pages(bo) < size)
3604
				continue;
3604
				continue;
3605
 
3605
 
3606
			kgem_bo_remove_from_active(kgem, bo);
3606
			kgem_bo_remove_from_active(kgem, bo);
3607
 
3607
 
3608
			bo->pitch = pitch;
3608
			bo->pitch = pitch;
3609
			bo->unique_id = kgem_get_unique_id(kgem);
3609
			bo->unique_id = kgem_get_unique_id(kgem);
3610
			bo->delta = 0;
3610
			bo->delta = 0;
3611
			DBG(("  1:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n",
3611
			DBG(("  1:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n",
3612
			     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
3612
			     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
3613
			assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
3613
			assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
3614
			assert_tiling(kgem, bo);
3614
			assert_tiling(kgem, bo);
3615
			bo->refcnt = 1;
3615
			bo->refcnt = 1;
3616
			return bo;
3616
			return bo;
3617
		}
3617
		}
3618
	}
3618
	}
3619
 
3619
 
3620
	if (--retry && exact) {
3620
	if (--retry && exact) {
3621
		if (kgem->gen >= 040) {
3621
		if (kgem->gen >= 040) {
3622
			for (i = I915_TILING_NONE; i <= I915_TILING_Y; i++) {
3622
			for (i = I915_TILING_NONE; i <= I915_TILING_Y; i++) {
3623
				if (i == tiling)
3623
				if (i == tiling)
3624
					continue;
3624
					continue;
3625
 
3625
 
3626
				cache = &kgem->active[bucket][i];
3626
				cache = &kgem->active[bucket][i];
3627
				list_for_each_entry(bo, cache, list) {
3627
				list_for_each_entry(bo, cache, list) {
3628
					assert(!bo->purged);
3628
					assert(!bo->purged);
3629
					assert(bo->refcnt == 0);
3629
					assert(bo->refcnt == 0);
3630
					assert(bo->reusable);
3630
					assert(bo->reusable);
3631
					assert(!bo->scanout);
3631
					assert(!bo->scanout);
3632
					assert(bo->flush == false);
3632
					assert(bo->flush == false);
3633
					assert_tiling(kgem, bo);
3633
					assert_tiling(kgem, bo);
3634
 
3634
 
3635
					if (num_pages(bo) < size)
3635
					if (num_pages(bo) < size)
3636
						continue;
3636
						continue;
3637
 
3637
 
3638
					if (!gem_set_tiling(kgem->fd,
3638
					if (!gem_set_tiling(kgem->fd,
3639
							    bo->handle,
3639
							    bo->handle,
3640
							    tiling, pitch))
3640
							    tiling, pitch))
3641
						continue;
3641
						continue;
3642
 
3642
 
3643
					kgem_bo_remove_from_active(kgem, bo);
3643
					kgem_bo_remove_from_active(kgem, bo);
3644
 
3644
 
3645
					bo->unique_id = kgem_get_unique_id(kgem);
3645
					bo->unique_id = kgem_get_unique_id(kgem);
3646
					bo->pitch = pitch;
3646
					bo->pitch = pitch;
3647
					bo->tiling = tiling;
3647
					bo->tiling = tiling;
3648
					bo->delta = 0;
3648
					bo->delta = 0;
3649
					DBG(("  1:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n",
3649
					DBG(("  1:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n",
3650
					     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
3650
					     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
3651
					assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
3651
					assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
3652
					assert_tiling(kgem, bo);
3652
					assert_tiling(kgem, bo);
3653
					bo->refcnt = 1;
3653
					bo->refcnt = 1;
3654
					return bo;
3654
					return bo;
3655
				}
3655
				}
3656
			}
3656
			}
3657
		}
3657
		}
3658
 
3658
 
3659
		bucket++;
3659
		bucket++;
3660
		goto search_again;
3660
		goto search_again;
3661
	}
3661
	}
3662
 
3662
 
3663
	if (!exact) { /* allow an active near-miss? */
3663
	if (!exact) { /* allow an active near-miss? */
3664
		i = tiling;
3664
		i = tiling;
3665
		while (--i >= 0) {
3665
		while (--i >= 0) {
3666
			tiled_height = kgem_surface_size(kgem, kgem->has_relaxed_fencing, flags,
3666
			tiled_height = kgem_surface_size(kgem, kgem->has_relaxed_fencing, flags,
3667
							 width, height, bpp, tiling, &pitch);
3667
							 width, height, bpp, tiling, &pitch);
3668
			cache = active(kgem, tiled_height / PAGE_SIZE, i);
3668
			cache = active(kgem, tiled_height / PAGE_SIZE, i);
3669
			tiled_height = kgem_aligned_height(kgem, height, i);
3669
			tiled_height = kgem_aligned_height(kgem, height, i);
3670
			list_for_each_entry(bo, cache, list) {
3670
			list_for_each_entry(bo, cache, list) {
3671
				assert(!bo->purged);
3671
				assert(!bo->purged);
3672
				assert(bo->refcnt == 0);
3672
				assert(bo->refcnt == 0);
3673
				assert(bo->reusable);
3673
				assert(bo->reusable);
3674
				assert(!bo->scanout);
3674
				assert(!bo->scanout);
3675
				assert(bo->flush == false);
3675
				assert(bo->flush == false);
3676
				assert_tiling(kgem, bo);
3676
				assert_tiling(kgem, bo);
3677
 
3677
 
3678
				if (bo->tiling) {
3678
				if (bo->tiling) {
3679
					if (bo->pitch < pitch) {
3679
					if (bo->pitch < pitch) {
3680
						DBG(("tiled and pitch too small: tiling=%d, (want %d), pitch=%d, need %d\n",
3680
						DBG(("tiled and pitch too small: tiling=%d, (want %d), pitch=%d, need %d\n",
3681
						     bo->tiling, tiling,
3681
						     bo->tiling, tiling,
3682
						     bo->pitch, pitch));
3682
						     bo->pitch, pitch));
3683
						continue;
3683
						continue;
3684
					}
3684
					}
3685
				} else
3685
				} else
3686
					bo->pitch = pitch;
3686
					bo->pitch = pitch;
3687
 
3687
 
3688
				if (bo->pitch * tiled_height > bytes(bo))
3688
				if (bo->pitch * tiled_height > bytes(bo))
3689
					continue;
3689
					continue;
3690
 
3690
 
3691
				kgem_bo_remove_from_active(kgem, bo);
3691
				kgem_bo_remove_from_active(kgem, bo);
3692
 
3692
 
3693
				bo->unique_id = kgem_get_unique_id(kgem);
3693
				bo->unique_id = kgem_get_unique_id(kgem);
3694
				bo->delta = 0;
3694
				bo->delta = 0;
3695
				DBG(("  1:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n",
3695
				DBG(("  1:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n",
3696
				     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
3696
				     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
3697
				assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
3697
				assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
3698
				assert_tiling(kgem, bo);
3698
				assert_tiling(kgem, bo);
3699
				bo->refcnt = 1;
3699
				bo->refcnt = 1;
3700
				return bo;
3700
				return bo;
3701
			}
3701
			}
3702
		}
3702
		}
3703
	}
3703
	}
3704
 
3704
 
3705
skip_active_search:
3705
skip_active_search:
3706
	bucket = cache_bucket(size);
3706
	bucket = cache_bucket(size);
3707
	retry = NUM_CACHE_BUCKETS - bucket;
3707
	retry = NUM_CACHE_BUCKETS - bucket;
3708
	if (retry > 3)
3708
	if (retry > 3)
3709
		retry = 3;
3709
		retry = 3;
3710
search_inactive:
3710
search_inactive:
3711
	/* Now just look for a close match and prefer any currently active */
3711
	/* Now just look for a close match and prefer any currently active */
3712
	assert(bucket < NUM_CACHE_BUCKETS);
3712
	assert(bucket < NUM_CACHE_BUCKETS);
3713
	cache = &kgem->inactive[bucket];
3713
	cache = &kgem->inactive[bucket];
3714
	list_for_each_entry(bo, cache, list) {
3714
	list_for_each_entry(bo, cache, list) {
3715
		assert(bucket(bo) == bucket);
3715
		assert(bucket(bo) == bucket);
3716
		assert(bo->reusable);
3716
		assert(bo->reusable);
3717
		assert(!bo->scanout);
3717
		assert(!bo->scanout);
3718
		assert(bo->flush == false);
3718
		assert(bo->flush == false);
3719
		assert_tiling(kgem, bo);
3719
		assert_tiling(kgem, bo);
3720
 
3720
 
3721
		if (size > num_pages(bo)) {
3721
		if (size > num_pages(bo)) {
3722
			DBG(("inactive too small: %d < %d\n",
3722
			DBG(("inactive too small: %d < %d\n",
3723
			     num_pages(bo), size));
3723
			     num_pages(bo), size));
3724
			continue;
3724
			continue;
3725
		}
3725
		}
3726
 
3726
 
3727
		if (bo->tiling != tiling ||
3727
		if (bo->tiling != tiling ||
3728
		    (tiling != I915_TILING_NONE && bo->pitch != pitch)) {
3728
		    (tiling != I915_TILING_NONE && bo->pitch != pitch)) {
3729
			if (!gem_set_tiling(kgem->fd, bo->handle,
3729
			if (!gem_set_tiling(kgem->fd, bo->handle,
3730
					    tiling, pitch))
3730
					    tiling, pitch))
3731
				continue;
3731
				continue;
3732
 
3732
 
3733
			if (bo->map)
3733
			if (bo->map)
3734
				kgem_bo_release_map(kgem, bo);
3734
				kgem_bo_release_map(kgem, bo);
3735
		}
3735
		}
3736
 
3736
 
3737
		if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
3737
		if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
3738
			kgem_bo_free(kgem, bo);
3738
			kgem_bo_free(kgem, bo);
3739
			break;
3739
			break;
3740
		}
3740
		}
3741
 
3741
 
3742
		kgem_bo_remove_from_inactive(kgem, bo);
3742
		kgem_bo_remove_from_inactive(kgem, bo);
3743
 
3743
 
3744
		bo->pitch = pitch;
3744
		bo->pitch = pitch;
3745
		bo->tiling = tiling;
3745
		bo->tiling = tiling;
3746
 
3746
 
3747
		bo->delta = 0;
3747
		bo->delta = 0;
3748
		bo->unique_id = kgem_get_unique_id(kgem);
3748
		bo->unique_id = kgem_get_unique_id(kgem);
3749
		assert(bo->pitch);
3749
		assert(bo->pitch);
3750
		DBG(("  from inactive: pitch=%d, tiling=%d: handle=%d, id=%d\n",
3750
		DBG(("  from inactive: pitch=%d, tiling=%d: handle=%d, id=%d\n",
3751
		     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
3751
		     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
3752
		assert(bo->refcnt == 0);
3752
		assert(bo->refcnt == 0);
3753
		assert(bo->reusable);
3753
		assert(bo->reusable);
3754
		assert((flags & CREATE_INACTIVE) == 0 || bo->domain != DOMAIN_GPU);
3754
		assert((flags & CREATE_INACTIVE) == 0 || bo->domain != DOMAIN_GPU);
3755
		ASSERT_MAYBE_IDLE(kgem, bo->handle, flags & CREATE_INACTIVE);
3755
		ASSERT_MAYBE_IDLE(kgem, bo->handle, flags & CREATE_INACTIVE);
3756
		assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
3756
		assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
3757
		assert_tiling(kgem, bo);
3757
		assert_tiling(kgem, bo);
3758
		bo->refcnt = 1;
3758
		bo->refcnt = 1;
3759
		return bo;
3759
		return bo;
3760
	}
3760
	}
3761
 
3761
 
3762
	if (flags & CREATE_INACTIVE &&
3762
	if (flags & CREATE_INACTIVE &&
3763
	    !list_is_empty(&kgem->active[bucket][tiling]) &&
3763
	    !list_is_empty(&kgem->active[bucket][tiling]) &&
3764
	    __kgem_throttle_retire(kgem, flags)) {
3764
	    __kgem_throttle_retire(kgem, flags)) {
3765
		flags &= ~CREATE_INACTIVE;
3765
		flags &= ~CREATE_INACTIVE;
3766
		goto search_inactive;
3766
		goto search_inactive;
3767
	}
3767
	}
3768
 
3768
 
3769
	if (--retry) {
3769
	if (--retry) {
3770
		bucket++;
3770
		bucket++;
3771
		flags &= ~CREATE_INACTIVE;
3771
		flags &= ~CREATE_INACTIVE;
3772
		goto search_inactive;
3772
		goto search_inactive;
3773
	}
3773
	}
3774
 
3774
 
3775
create:
3775
create:
3776
	if (flags & CREATE_CACHED)
3776
	if (flags & CREATE_CACHED)
3777
		return NULL;
3777
		return NULL;
3778
 
3778
 
3779
	if (bucket >= NUM_CACHE_BUCKETS)
3779
	if (bucket >= NUM_CACHE_BUCKETS)
3780
		size = ALIGN(size, 1024);
3780
		size = ALIGN(size, 1024);
3781
	handle = gem_create(kgem->fd, size);
3781
	handle = gem_create(kgem->fd, size);
3782
	if (handle == 0)
3782
	if (handle == 0)
3783
		return NULL;
3783
		return NULL;
3784
 
3784
 
3785
	bo = __kgem_bo_alloc(handle, size);
3785
	bo = __kgem_bo_alloc(handle, size);
3786
	if (!bo) {
3786
	if (!bo) {
3787
		gem_close(kgem->fd, handle);
3787
		gem_close(kgem->fd, handle);
3788
		return NULL;
3788
		return NULL;
3789
	}
3789
	}
3790
 
3790
 
3791
	if (bucket >= NUM_CACHE_BUCKETS) {
3791
	if (bucket >= NUM_CACHE_BUCKETS) {
3792
		DBG(("%s: marking large bo for automatic flushing\n",
3792
		DBG(("%s: marking large bo for automatic flushing\n",
3793
		     __FUNCTION__));
3793
		     __FUNCTION__));
3794
		bo->flush = true;
3794
		bo->flush = true;
3795
	}
3795
	}
3796
 
3796
 
3797
	bo->unique_id = kgem_get_unique_id(kgem);
3797
	bo->unique_id = kgem_get_unique_id(kgem);
3798
	if (tiling == I915_TILING_NONE ||
3798
	if (tiling == I915_TILING_NONE ||
3799
	    gem_set_tiling(kgem->fd, handle, tiling, pitch)) {
3799
	    gem_set_tiling(kgem->fd, handle, tiling, pitch)) {
3800
		bo->tiling = tiling;
3800
		bo->tiling = tiling;
3801
		bo->pitch = pitch;
3801
		bo->pitch = pitch;
3802
	} else {
3802
	} else {
3803
		if (flags & CREATE_EXACT) {
3803
		if (flags & CREATE_EXACT) {
3804
			if (bo->pitch != pitch || bo->tiling != tiling) {
3804
			if (bo->pitch != pitch || bo->tiling != tiling) {
3805
				kgem_bo_free(kgem, bo);
3805
				kgem_bo_free(kgem, bo);
3806
				return NULL;
3806
				return NULL;
3807
			}
3807
			}
3808
		}
3808
		}
3809
	}
3809
	}
3810
 
3810
 
3811
	assert(bytes(bo) >= bo->pitch * kgem_aligned_height(kgem, height, bo->tiling));
3811
	assert(bytes(bo) >= bo->pitch * kgem_aligned_height(kgem, height, bo->tiling));
3812
	assert_tiling(kgem, bo);
3812
	assert_tiling(kgem, bo);
3813
 
3813
 
3814
	debug_alloc__bo(kgem, bo);
3814
	debug_alloc__bo(kgem, bo);
3815
 
3815
 
3816
	DBG(("  new pitch=%d, tiling=%d, handle=%d, id=%d, num_pages=%d [%d], bucket=%d\n",
3816
	DBG(("  new pitch=%d, tiling=%d, handle=%d, id=%d, num_pages=%d [%d], bucket=%d\n",
3817
	     bo->pitch, bo->tiling, bo->handle, bo->unique_id,
3817
	     bo->pitch, bo->tiling, bo->handle, bo->unique_id,
3818
	     size, num_pages(bo), bucket(bo)));
3818
	     size, num_pages(bo), bucket(bo)));
3819
	return bo;
3819
	return bo;
3820
}
3820
}
3821
 
3821
 
3822
#if 0
3822
#if 0
3823
struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem,
3823
struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem,
3824
				   int width,
3824
				   int width,
3825
				   int height,
3825
				   int height,
3826
				   int bpp,
3826
				   int bpp,
3827
				   uint32_t flags)
3827
				   uint32_t flags)
3828
{
3828
{
3829
	struct kgem_bo *bo;
3829
	struct kgem_bo *bo;
3830
	int stride, size;
3830
	int stride, size;
3831
 
3831
 
3832
	if (DBG_NO_CPU)
3832
	if (DBG_NO_CPU)
3833
		return NULL;
3833
		return NULL;
3834
 
3834
 
3835
	DBG(("%s(%dx%d, bpp=%d)\n", __FUNCTION__, width, height, bpp));
3835
	DBG(("%s(%dx%d, bpp=%d)\n", __FUNCTION__, width, height, bpp));
3836
 
3836
 
3837
	if (kgem->has_llc) {
3837
	if (kgem->has_llc) {
3838
		bo = kgem_create_2d(kgem, width, height, bpp,
3838
		bo = kgem_create_2d(kgem, width, height, bpp,
3839
				    I915_TILING_NONE, flags);
3839
				    I915_TILING_NONE, flags);
3840
		if (bo == NULL)
3840
		if (bo == NULL)
3841
			return bo;
3841
			return bo;
3842
 
3842
 
3843
		assert(bo->tiling == I915_TILING_NONE);
3843
		assert(bo->tiling == I915_TILING_NONE);
3844
		assert_tiling(kgem, bo);
3844
		assert_tiling(kgem, bo);
3845
 
3845
 
3846
		if (kgem_bo_map__cpu(kgem, bo) == NULL) {
3846
		if (kgem_bo_map__cpu(kgem, bo) == NULL) {
3847
			kgem_bo_destroy(kgem, bo);
3847
			kgem_bo_destroy(kgem, bo);
3848
			return NULL;
3848
			return NULL;
3849
		}
3849
		}
3850
 
3850
 
3851
		return bo;
3851
		return bo;
3852
	}
3852
	}
3853
 
3853
 
3854
	assert(width > 0 && height > 0);
3854
	assert(width > 0 && height > 0);
3855
	stride = ALIGN(width, 2) * bpp >> 3;
3855
	stride = ALIGN(width, 2) * bpp >> 3;
3856
	stride = ALIGN(stride, 4);
3856
	stride = ALIGN(stride, 4);
3857
	size = stride * ALIGN(height, 2);
3857
	size = stride * ALIGN(height, 2);
3858
	assert(size >= PAGE_SIZE);
3858
	assert(size >= PAGE_SIZE);
3859
 
3859
 
3860
	DBG(("%s: %dx%d, %d bpp, stride=%d\n",
3860
	DBG(("%s: %dx%d, %d bpp, stride=%d\n",
3861
	     __FUNCTION__, width, height, bpp, stride));
3861
	     __FUNCTION__, width, height, bpp, stride));
3862
 
3862
 
3863
	bo = search_snoop_cache(kgem, NUM_PAGES(size), 0);
3863
	bo = search_snoop_cache(kgem, NUM_PAGES(size), 0);
3864
	if (bo) {
3864
	if (bo) {
3865
		assert(bo->tiling == I915_TILING_NONE);
3865
		assert(bo->tiling == I915_TILING_NONE);
3866
		assert_tiling(kgem, bo);
3866
		assert_tiling(kgem, bo);
3867
		assert(bo->snoop);
3867
		assert(bo->snoop);
3868
		bo->refcnt = 1;
3868
		bo->refcnt = 1;
3869
		bo->pitch = stride;
3869
		bo->pitch = stride;
3870
		bo->unique_id = kgem_get_unique_id(kgem);
3870
		bo->unique_id = kgem_get_unique_id(kgem);
3871
		return bo;
3871
		return bo;
3872
	}
3872
	}
3873
 
3873
 
3874
	if (kgem->has_caching) {
3874
	if (kgem->has_caching) {
3875
		bo = kgem_create_linear(kgem, size, flags);
3875
		bo = kgem_create_linear(kgem, size, flags);
3876
		if (bo == NULL)
3876
		if (bo == NULL)
3877
			return NULL;
3877
			return NULL;
3878
 
3878
 
3879
		assert(bo->tiling == I915_TILING_NONE);
3879
		assert(bo->tiling == I915_TILING_NONE);
3880
		assert_tiling(kgem, bo);
3880
		assert_tiling(kgem, bo);
3881
 
3881
 
3882
		if (!gem_set_caching(kgem->fd, bo->handle, SNOOPED)) {
3882
		if (!gem_set_caching(kgem->fd, bo->handle, SNOOPED)) {
3883
			kgem_bo_destroy(kgem, bo);
3883
			kgem_bo_destroy(kgem, bo);
3884
			return NULL;
3884
			return NULL;
3885
		}
3885
		}
3886
		bo->snoop = true;
3886
		bo->snoop = true;
3887
 
3887
 
3888
		if (kgem_bo_map__cpu(kgem, bo) == NULL) {
3888
		if (kgem_bo_map__cpu(kgem, bo) == NULL) {
3889
			kgem_bo_destroy(kgem, bo);
3889
			kgem_bo_destroy(kgem, bo);
3890
			return NULL;
3890
			return NULL;
3891
		}
3891
		}
3892
 
3892
 
3893
		bo->pitch = stride;
3893
		bo->pitch = stride;
3894
		bo->unique_id = kgem_get_unique_id(kgem);
3894
		bo->unique_id = kgem_get_unique_id(kgem);
3895
		return bo;
3895
		return bo;
3896
	}
3896
	}
3897
 
3897
 
3898
	if (kgem->has_userptr) {
3898
	if (kgem->has_userptr) {
3899
		void *ptr;
3899
		void *ptr;
3900
 
3900
 
3901
		/* XXX */
3901
		/* XXX */
3902
		//if (posix_memalign(&ptr, 64, ALIGN(size, 64)))
3902
		//if (posix_memalign(&ptr, 64, ALIGN(size, 64)))
3903
		if (posix_memalign(&ptr, PAGE_SIZE, ALIGN(size, PAGE_SIZE)))
3903
		if (posix_memalign(&ptr, PAGE_SIZE, ALIGN(size, PAGE_SIZE)))
3904
			return NULL;
3904
			return NULL;
3905
 
3905
 
3906
		bo = kgem_create_map(kgem, ptr, size, false);
3906
		bo = kgem_create_map(kgem, ptr, size, false);
3907
		if (bo == NULL) {
3907
		if (bo == NULL) {
3908
			free(ptr);
3908
			free(ptr);
3909
			return NULL;
3909
			return NULL;
3910
		}
3910
		}
3911
 
3911
 
3912
		bo->pitch = stride;
3912
		bo->pitch = stride;
3913
		bo->unique_id = kgem_get_unique_id(kgem);
3913
		bo->unique_id = kgem_get_unique_id(kgem);
3914
		return bo;
3914
		return bo;
3915
	}
3915
	}
3916
 
3916
 
3917
		return NULL;
3917
		return NULL;
3918
}
3918
}
3919
#endif
3919
#endif
3920
 
3920
 
3921
void _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
3921
void _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
3922
{
3922
{
3923
	DBG(("%s: handle=%d, proxy? %d\n",
3923
	DBG(("%s: handle=%d, proxy? %d\n",
3924
	     __FUNCTION__, bo->handle, bo->proxy != NULL));
3924
	     __FUNCTION__, bo->handle, bo->proxy != NULL));
3925
 
3925
 
3926
	if (bo->proxy) {
3926
	if (bo->proxy) {
3927
		_list_del(&bo->vma);
3927
		_list_del(&bo->vma);
3928
		_list_del(&bo->request);
3928
		_list_del(&bo->request);
3929
		if (bo->io && bo->exec == NULL)
3929
		if (bo->io && bo->exec == NULL)
3930
			_kgem_bo_delete_buffer(kgem, bo);
3930
			_kgem_bo_delete_buffer(kgem, bo);
3931
		kgem_bo_unref(kgem, bo->proxy);
3931
		kgem_bo_unref(kgem, bo->proxy);
3932
		kgem_bo_binding_free(kgem, bo);
3932
		kgem_bo_binding_free(kgem, bo);
3933
		free(bo);
3933
		free(bo);
3934
		return;
3934
		return;
3935
		}
3935
		}
3936
 
3936
 
3937
	__kgem_bo_destroy(kgem, bo);
3937
	__kgem_bo_destroy(kgem, bo);
3938
}
3938
}
3939
 
3939
 
3940
static void __kgem_flush(struct kgem *kgem, struct kgem_bo *bo)
3940
static void __kgem_flush(struct kgem *kgem, struct kgem_bo *bo)
3941
{
3941
{
3942
	assert(bo->rq);
3942
	assert(bo->rq);
3943
	assert(bo->exec == NULL);
3943
	assert(bo->exec == NULL);
3944
	assert(bo->needs_flush);
3944
	assert(bo->needs_flush);
3945
 
3945
 
3946
	/* The kernel will emit a flush *and* update its own flushing lists. */
3946
	/* The kernel will emit a flush *and* update its own flushing lists. */
3947
	if (!__kgem_busy(kgem, bo->handle))
3947
	if (!__kgem_busy(kgem, bo->handle))
3948
		__kgem_bo_clear_busy(bo);
3948
		__kgem_bo_clear_busy(bo);
3949
 
3949
 
3950
	DBG(("%s: handle=%d, busy?=%d\n",
3950
	DBG(("%s: handle=%d, busy?=%d\n",
3951
	     __FUNCTION__, bo->handle, bo->rq != NULL));
3951
	     __FUNCTION__, bo->handle, bo->rq != NULL));
3952
}
3952
}
3953
 
3953
 
3954
void kgem_scanout_flush(struct kgem *kgem, struct kgem_bo *bo)
3954
void kgem_scanout_flush(struct kgem *kgem, struct kgem_bo *bo)
3955
{
3955
{
3956
	kgem_bo_submit(kgem, bo);
3956
	kgem_bo_submit(kgem, bo);
3957
	if (!bo->needs_flush)
3957
	if (!bo->needs_flush)
3958
		return;
3958
		return;
3959
 
3959
 
3960
	/* If the kernel fails to emit the flush, then it will be forced when
3960
	/* If the kernel fails to emit the flush, then it will be forced when
3961
	 * we assume direct access. And as the usual failure is EIO, we do
3961
	 * we assume direct access. And as the usual failure is EIO, we do
3962
	 * not actually care.
3962
	 * not actually care.
3963
	 */
3963
	 */
3964
	assert(bo->exec == NULL);
3964
	assert(bo->exec == NULL);
3965
	if (bo->rq)
3965
	if (bo->rq)
3966
		__kgem_flush(kgem, bo);
3966
		__kgem_flush(kgem, bo);
3967
 
3967
 
3968
	/* Whatever actually happens, we can regard the GTT write domain
3968
	/* Whatever actually happens, we can regard the GTT write domain
3969
	 * as being flushed.
3969
	 * as being flushed.
3970
	 */
3970
	 */
3971
	bo->gtt_dirty = false;
3971
	bo->gtt_dirty = false;
3972
	bo->needs_flush = false;
3972
	bo->needs_flush = false;
3973
	bo->domain = DOMAIN_NONE;
3973
	bo->domain = DOMAIN_NONE;
3974
}
3974
}
3975
 
3975
 
3976
inline static bool needs_semaphore(struct kgem *kgem, struct kgem_bo *bo)
3976
inline static bool needs_semaphore(struct kgem *kgem, struct kgem_bo *bo)
3977
{
3977
{
3978
	return kgem->nreloc && bo->rq && RQ_RING(bo->rq) != kgem->ring;
3978
	return kgem->nreloc && bo->rq && RQ_RING(bo->rq) != kgem->ring;
3979
}
3979
}
3980
 
3980
 
3981
bool kgem_check_bo(struct kgem *kgem, ...)
3981
bool kgem_check_bo(struct kgem *kgem, ...)
3982
{
3982
{
3983
	va_list ap;
3983
	va_list ap;
3984
	struct kgem_bo *bo;
3984
	struct kgem_bo *bo;
3985
	int num_exec = 0;
3985
	int num_exec = 0;
3986
	int num_pages = 0;
3986
	int num_pages = 0;
3987
	bool flush = false;
3987
	bool flush = false;
3988
 
3988
 
3989
	va_start(ap, kgem);
3989
	va_start(ap, kgem);
3990
	while ((bo = va_arg(ap, struct kgem_bo *))) {
3990
	while ((bo = va_arg(ap, struct kgem_bo *))) {
3991
		while (bo->proxy)
3991
		while (bo->proxy)
3992
			bo = bo->proxy;
3992
			bo = bo->proxy;
3993
		if (bo->exec)
3993
		if (bo->exec)
3994
			continue;
3994
			continue;
3995
 
3995
 
3996
		if (needs_semaphore(kgem, bo))
3996
		if (needs_semaphore(kgem, bo))
3997
			return false;
3997
			return false;
3998
 
3998
 
3999
		num_pages += num_pages(bo);
3999
		num_pages += num_pages(bo);
4000
		num_exec++;
4000
		num_exec++;
4001
 
4001
 
4002
		flush |= bo->flush;
4002
		flush |= bo->flush;
4003
	}
4003
	}
4004
	va_end(ap);
4004
	va_end(ap);
4005
 
4005
 
4006
	DBG(("%s: num_pages=+%d, num_exec=+%d\n",
4006
	DBG(("%s: num_pages=+%d, num_exec=+%d\n",
4007
	     __FUNCTION__, num_pages, num_exec));
4007
	     __FUNCTION__, num_pages, num_exec));
4008
 
4008
 
4009
	if (!num_pages)
4009
	if (!num_pages)
4010
		return true;
4010
		return true;
4011
 
4011
 
4012
	if (kgem_flush(kgem, flush))
4012
	if (kgem_flush(kgem, flush))
4013
		return false;
4013
		return false;
4014
 
4014
 
4015
	if (kgem->aperture > kgem->aperture_low &&
4015
	if (kgem->aperture > kgem->aperture_low &&
4016
	    kgem_ring_is_idle(kgem, kgem->ring)) {
4016
	    kgem_ring_is_idle(kgem, kgem->ring)) {
4017
		DBG(("%s: current aperture usage (%d) is greater than low water mark (%d)\n",
4017
		DBG(("%s: current aperture usage (%d) is greater than low water mark (%d)\n",
4018
		     __FUNCTION__, kgem->aperture, kgem->aperture_low));
4018
		     __FUNCTION__, kgem->aperture, kgem->aperture_low));
4019
		return false;
4019
		return false;
4020
	}
4020
	}
4021
 
4021
 
4022
	if (num_pages + kgem->aperture > kgem->aperture_high) {
4022
	if (num_pages + kgem->aperture > kgem->aperture_high) {
4023
		DBG(("%s: final aperture usage (%d) is greater than high water mark (%d)\n",
4023
		DBG(("%s: final aperture usage (%d) is greater than high water mark (%d)\n",
4024
		     __FUNCTION__, num_pages + kgem->aperture, kgem->aperture_high));
4024
		     __FUNCTION__, num_pages + kgem->aperture, kgem->aperture_high));
4025
		return false;
4025
		return false;
4026
	}
4026
	}
4027
 
4027
 
4028
	if (kgem->nexec + num_exec >= KGEM_EXEC_SIZE(kgem)) {
4028
	if (kgem->nexec + num_exec >= KGEM_EXEC_SIZE(kgem)) {
4029
		DBG(("%s: out of exec slots (%d + %d / %d)\n", __FUNCTION__,
4029
		DBG(("%s: out of exec slots (%d + %d / %d)\n", __FUNCTION__,
4030
		     kgem->nexec, num_exec, KGEM_EXEC_SIZE(kgem)));
4030
		     kgem->nexec, num_exec, KGEM_EXEC_SIZE(kgem)));
4031
		return false;
4031
		return false;
4032
	}
4032
	}
4033
 
4033
 
4034
	return true;
4034
	return true;
4035
}
4035
}
4036
 
4036
 
4037
 
4037
 
4038
 
4038
 
4039
 
4039
 
4040
 
4040
 
4041
 
4041
 
4042
 
4042
 
4043
 
4043
 
4044
 
4044
 
4045
 
4045
 
4046
 
4046
 
4047
 
4047
 
4048
 
4048
 
4049
 
4049
 
4050
 
4050
 
4051
 
4051
 
4052
 
4052
 
4053
 
4053
 
4054
 
4054
 
4055
 
4055
 
4056
 
4056
 
4057
 
4057
 
4058
 
4058
 
4059
 
4059
 
4060
 
4060
 
4061
 
4061
 
4062
 
4062
 
4063
 
4063
 
4064
 
4064
 
4065
 
4065
 
4066
uint32_t kgem_add_reloc(struct kgem *kgem,
4066
uint32_t kgem_add_reloc(struct kgem *kgem,
4067
			uint32_t pos,
4067
			uint32_t pos,
4068
			struct kgem_bo *bo,
4068
			struct kgem_bo *bo,
4069
			uint32_t read_write_domain,
4069
			uint32_t read_write_domain,
4070
			uint32_t delta)
4070
			uint32_t delta)
4071
{
4071
{
4072
	int index;
4072
	int index;
4073
 
4073
 
4074
	DBG(("%s: handle=%d, pos=%d, delta=%d, domains=%08x\n",
4074
	DBG(("%s: handle=%d, pos=%d, delta=%d, domains=%08x\n",
4075
	     __FUNCTION__, bo ? bo->handle : 0, pos, delta, read_write_domain));
4075
	     __FUNCTION__, bo ? bo->handle : 0, pos, delta, read_write_domain));
4076
 
4076
 
4077
	assert((read_write_domain & 0x7fff) == 0 || bo != NULL);
4077
	assert((read_write_domain & 0x7fff) == 0 || bo != NULL);
4078
 
4078
 
4079
    if( bo != NULL && bo->handle == -2)
4079
    if( bo != NULL && bo->handle == -2)
4080
    {
4080
    {
4081
   		if (bo->exec == NULL)
4081
   		if (bo->exec == NULL)
4082
			kgem_add_bo(kgem, bo);
4082
			kgem_add_bo(kgem, bo);
4083
 
4083
 
4084
		if (read_write_domain & 0x7fff && !bo->gpu_dirty) {
4084
		if (read_write_domain & 0x7fff && !bo->gpu_dirty) {
4085
			__kgem_bo_mark_dirty(bo);
4085
			__kgem_bo_mark_dirty(bo);
4086
		}
4086
		}
4087
        return 0;
4087
        return 0;
4088
    };
4088
    };
4089
 
4089
 
4090
	index = kgem->nreloc++;
4090
	index = kgem->nreloc++;
4091
	assert(index < ARRAY_SIZE(kgem->reloc));
4091
	assert(index < ARRAY_SIZE(kgem->reloc));
4092
	kgem->reloc[index].offset = pos * sizeof(kgem->batch[0]);
4092
	kgem->reloc[index].offset = pos * sizeof(kgem->batch[0]);
4093
	if (bo) {
4093
	if (bo) {
4094
		assert(bo->refcnt);
4094
		assert(bo->refcnt);
4095
		while (bo->proxy) {
4095
		while (bo->proxy) {
4096
			DBG(("%s: adding proxy [delta=%d] for handle=%d\n",
4096
			DBG(("%s: adding proxy [delta=%d] for handle=%d\n",
4097
			     __FUNCTION__, bo->delta, bo->handle));
4097
			     __FUNCTION__, bo->delta, bo->handle));
4098
			delta += bo->delta;
4098
			delta += bo->delta;
4099
			assert(bo->handle == bo->proxy->handle);
4099
			assert(bo->handle == bo->proxy->handle);
4100
			/* need to release the cache upon batch submit */
4100
			/* need to release the cache upon batch submit */
4101
			if (bo->exec == NULL) {
4101
			if (bo->exec == NULL) {
4102
				list_move_tail(&bo->request,
4102
				list_move_tail(&bo->request,
4103
					       &kgem->next_request->buffers);
4103
					       &kgem->next_request->buffers);
4104
				bo->rq = MAKE_REQUEST(kgem->next_request,
4104
				bo->rq = MAKE_REQUEST(kgem->next_request,
4105
						      kgem->ring);
4105
						      kgem->ring);
4106
				bo->exec = &_kgem_dummy_exec;
4106
				bo->exec = &_kgem_dummy_exec;
4107
		}
4107
		}
4108
 
4108
 
4109
			if (read_write_domain & 0x7fff && !bo->gpu_dirty)
4109
			if (read_write_domain & 0x7fff && !bo->gpu_dirty)
4110
				__kgem_bo_mark_dirty(bo);
4110
				__kgem_bo_mark_dirty(bo);
4111
 
4111
 
4112
			bo = bo->proxy;
4112
			bo = bo->proxy;
4113
			assert(bo->refcnt);
4113
			assert(bo->refcnt);
4114
		}
4114
		}
4115
		assert(bo->refcnt);
4115
		assert(bo->refcnt);
4116
 
4116
 
4117
		if (bo->exec == NULL)
4117
		if (bo->exec == NULL)
4118
			kgem_add_bo(kgem, bo);
4118
			kgem_add_bo(kgem, bo);
4119
		assert(bo->rq == MAKE_REQUEST(kgem->next_request, kgem->ring));
4119
		assert(bo->rq == MAKE_REQUEST(kgem->next_request, kgem->ring));
4120
		assert(RQ_RING(bo->rq) == kgem->ring);
4120
		assert(RQ_RING(bo->rq) == kgem->ring);
4121
 
4121
 
4122
		if (kgem->gen < 040 && read_write_domain & KGEM_RELOC_FENCED) {
4122
		if (kgem->gen < 040 && read_write_domain & KGEM_RELOC_FENCED) {
4123
			if (bo->tiling &&
4123
			if (bo->tiling &&
4124
			    (bo->exec->flags & EXEC_OBJECT_NEEDS_FENCE) == 0) {
4124
			    (bo->exec->flags & EXEC_OBJECT_NEEDS_FENCE) == 0) {
4125
				assert(kgem->nfence < kgem->fence_max);
4125
				assert(kgem->nfence < kgem->fence_max);
4126
				kgem->aperture_fenced +=
4126
				kgem->aperture_fenced +=
4127
					kgem_bo_fenced_size(kgem, bo);
4127
					kgem_bo_fenced_size(kgem, bo);
4128
				kgem->nfence++;
4128
				kgem->nfence++;
4129
			}
4129
			}
4130
			bo->exec->flags |= EXEC_OBJECT_NEEDS_FENCE;
4130
			bo->exec->flags |= EXEC_OBJECT_NEEDS_FENCE;
4131
		}
4131
		}
4132
 
4132
 
4133
		kgem->reloc[index].delta = delta;
4133
		kgem->reloc[index].delta = delta;
4134
		kgem->reloc[index].target_handle = bo->target_handle;
4134
		kgem->reloc[index].target_handle = bo->target_handle;
4135
		kgem->reloc[index].presumed_offset = bo->presumed_offset;
4135
		kgem->reloc[index].presumed_offset = bo->presumed_offset;
4136
 
4136
 
4137
		if (read_write_domain & 0x7fff && !bo->gpu_dirty) {
4137
		if (read_write_domain & 0x7fff && !bo->gpu_dirty) {
4138
			assert(!bo->snoop || kgem->can_blt_cpu);
4138
			assert(!bo->snoop || kgem->can_blt_cpu);
4139
			__kgem_bo_mark_dirty(bo);
4139
			__kgem_bo_mark_dirty(bo);
4140
		}
4140
		}
4141
 
4141
 
4142
		delta += bo->presumed_offset;
4142
		delta += bo->presumed_offset;
4143
	} else {
4143
	} else {
4144
		kgem->reloc[index].delta = delta;
4144
		kgem->reloc[index].delta = delta;
4145
		kgem->reloc[index].target_handle = ~0U;
4145
		kgem->reloc[index].target_handle = ~0U;
4146
		kgem->reloc[index].presumed_offset = 0;
4146
		kgem->reloc[index].presumed_offset = 0;
4147
		if (kgem->nreloc__self < 256)
4147
		if (kgem->nreloc__self < 256)
4148
			kgem->reloc__self[kgem->nreloc__self++] = index;
4148
			kgem->reloc__self[kgem->nreloc__self++] = index;
4149
		}
4149
		}
4150
	kgem->reloc[index].read_domains = read_write_domain >> 16;
4150
	kgem->reloc[index].read_domains = read_write_domain >> 16;
4151
	kgem->reloc[index].write_domain = read_write_domain & 0x7fff;
4151
	kgem->reloc[index].write_domain = read_write_domain & 0x7fff;
4152
 
4152
 
4153
	return delta;
4153
	return delta;
4154
}
4154
}
4155
 
4155
 
4156
static void kgem_trim_vma_cache(struct kgem *kgem, int type, int bucket)
4156
static void kgem_trim_vma_cache(struct kgem *kgem, int type, int bucket)
4157
{
4157
{
4158
	int i, j;
4158
	int i, j;
4159
 
4159
 
4160
	DBG(("%s: type=%d, count=%d (bucket: %d)\n",
4160
	DBG(("%s: type=%d, count=%d (bucket: %d)\n",
4161
	     __FUNCTION__, type, kgem->vma[type].count, bucket));
4161
	     __FUNCTION__, type, kgem->vma[type].count, bucket));
4162
	if (kgem->vma[type].count <= 0)
4162
	if (kgem->vma[type].count <= 0)
4163
	       return;
4163
	       return;
4164
 
4164
 
4165
	if (kgem->need_purge)
4165
	if (kgem->need_purge)
4166
		kgem_purge_cache(kgem);
4166
		kgem_purge_cache(kgem);
4167
 
4167
 
4168
	/* vma are limited on a per-process basis to around 64k.
4168
	/* vma are limited on a per-process basis to around 64k.
4169
	 * This includes all malloc arenas as well as other file
4169
	 * This includes all malloc arenas as well as other file
4170
	 * mappings. In order to be fair and not hog the cache,
4170
	 * mappings. In order to be fair and not hog the cache,
4171
	 * and more importantly not to exhaust that limit and to
4171
	 * and more importantly not to exhaust that limit and to
4172
	 * start failing mappings, we keep our own number of open
4172
	 * start failing mappings, we keep our own number of open
4173
	 * vma to within a conservative value.
4173
	 * vma to within a conservative value.
4174
	 */
4174
	 */
4175
	i = 0;
4175
	i = 0;
4176
	while (kgem->vma[type].count > 0) {
4176
	while (kgem->vma[type].count > 0) {
4177
		struct kgem_bo *bo = NULL;
4177
		struct kgem_bo *bo = NULL;
4178
 
4178
 
4179
		for (j = 0;
4179
		for (j = 0;
4180
		     bo == NULL && j < ARRAY_SIZE(kgem->vma[type].inactive);
4180
		     bo == NULL && j < ARRAY_SIZE(kgem->vma[type].inactive);
4181
		     j++) {
4181
		     j++) {
4182
			struct list *head = &kgem->vma[type].inactive[i++%ARRAY_SIZE(kgem->vma[type].inactive)];
4182
			struct list *head = &kgem->vma[type].inactive[i++%ARRAY_SIZE(kgem->vma[type].inactive)];
4183
			if (!list_is_empty(head))
4183
			if (!list_is_empty(head))
4184
				bo = list_last_entry(head, struct kgem_bo, vma);
4184
				bo = list_last_entry(head, struct kgem_bo, vma);
4185
	}
4185
	}
4186
		if (bo == NULL)
4186
		if (bo == NULL)
4187
			break;
4187
			break;
4188
 
4188
 
4189
		DBG(("%s: discarding inactive %s vma cache for %d\n",
4189
		DBG(("%s: discarding inactive %s vma cache for %d\n",
4190
		     __FUNCTION__,
4190
		     __FUNCTION__,
4191
		     IS_CPU_MAP(bo->map) ? "CPU" : "GTT", bo->handle));
4191
		     IS_CPU_MAP(bo->map) ? "CPU" : "GTT", bo->handle));
4192
		assert(IS_CPU_MAP(bo->map) == type);
4192
		assert(IS_CPU_MAP(bo->map) == type);
4193
		assert(bo->map);
4193
		assert(bo->map);
4194
			assert(bo->rq == NULL);
4194
			assert(bo->rq == NULL);
4195
 
4195
 
4196
		VG(if (type) VALGRIND_MAKE_MEM_NOACCESS(MAP(bo->map), bytes(bo)));
4196
		VG(if (type) VALGRIND_MAKE_MEM_NOACCESS(MAP(bo->map), bytes(bo)));
4197
//		munmap(MAP(bo->map), bytes(bo));
4197
//		munmap(MAP(bo->map), bytes(bo));
4198
		bo->map = NULL;
4198
		bo->map = NULL;
4199
		list_del(&bo->vma);
4199
		list_del(&bo->vma);
4200
		kgem->vma[type].count--;
4200
		kgem->vma[type].count--;
4201
 
4201
 
4202
		if (!bo->purged && !kgem_bo_set_purgeable(kgem, bo)) {
4202
		if (!bo->purged && !kgem_bo_set_purgeable(kgem, bo)) {
4203
			DBG(("%s: freeing unpurgeable old mapping\n",
4203
			DBG(("%s: freeing unpurgeable old mapping\n",
4204
			     __FUNCTION__));
4204
			     __FUNCTION__));
4205
				kgem_bo_free(kgem, bo);
4205
				kgem_bo_free(kgem, bo);
4206
			}
4206
			}
4207
	}
4207
	}
4208
}
4208
}
4209
 
4209
 
4210
void *kgem_bo_map__async(struct kgem *kgem, struct kgem_bo *bo)
4210
void *kgem_bo_map__async(struct kgem *kgem, struct kgem_bo *bo)
4211
{
4211
{
4212
	void *ptr;
4212
	void *ptr;
4213
 
4213
 
4214
	DBG(("%s: handle=%d, offset=%d, tiling=%d, map=%p, domain=%d\n", __FUNCTION__,
4214
	DBG(("%s: handle=%d, offset=%d, tiling=%d, map=%p, domain=%d\n", __FUNCTION__,
4215
	     bo->handle, bo->presumed_offset, bo->tiling, bo->map, bo->domain));
4215
	     bo->handle, bo->presumed_offset, bo->tiling, bo->map, bo->domain));
4216
 
4216
 
4217
	assert(bo->proxy == NULL);
4217
	assert(bo->proxy == NULL);
4218
	assert(list_is_empty(&bo->list));
4218
	assert(list_is_empty(&bo->list));
4219
	assert(!IS_USER_MAP(bo->map));
4219
	assert(!IS_USER_MAP(bo->map));
4220
	assert_tiling(kgem, bo);
4220
	assert_tiling(kgem, bo);
4221
 
4221
 
4222
	if (bo->tiling == I915_TILING_NONE && !bo->scanout && kgem->has_llc) {
4222
	if (bo->tiling == I915_TILING_NONE && !bo->scanout && kgem->has_llc) {
4223
		DBG(("%s: converting request for GTT map into CPU map\n",
4223
		DBG(("%s: converting request for GTT map into CPU map\n",
4224
		     __FUNCTION__));
4224
		     __FUNCTION__));
4225
		return kgem_bo_map__cpu(kgem, bo);
4225
		return kgem_bo_map__cpu(kgem, bo);
4226
	}
4226
	}
4227
 
4227
 
4228
	if (IS_CPU_MAP(bo->map))
4228
	if (IS_CPU_MAP(bo->map))
4229
		kgem_bo_release_map(kgem, bo);
4229
		kgem_bo_release_map(kgem, bo);
4230
 
4230
 
4231
	ptr = bo->map;
4231
	ptr = bo->map;
4232
	if (ptr == NULL) {
4232
	if (ptr == NULL) {
4233
		assert(kgem_bo_size(bo) <= kgem->aperture_mappable / 2);
4233
		assert(kgem_bo_size(bo) <= kgem->aperture_mappable / 2);
4234
 
4234
 
4235
		kgem_trim_vma_cache(kgem, MAP_GTT, bucket(bo));
4235
		kgem_trim_vma_cache(kgem, MAP_GTT, bucket(bo));
4236
 
4236
 
4237
		ptr = __kgem_bo_map__gtt(kgem, bo);
4237
		ptr = __kgem_bo_map__gtt(kgem, bo);
4238
		if (ptr == NULL)
4238
		if (ptr == NULL)
4239
			return NULL;
4239
			return NULL;
4240
 
4240
 
4241
		/* Cache this mapping to avoid the overhead of an
4241
		/* Cache this mapping to avoid the overhead of an
4242
		 * excruciatingly slow GTT pagefault. This is more an
4242
		 * excruciatingly slow GTT pagefault. This is more an
4243
		 * issue with compositing managers which need to frequently
4243
		 * issue with compositing managers which need to frequently
4244
		 * flush CPU damage to their GPU bo.
4244
		 * flush CPU damage to their GPU bo.
4245
		 */
4245
		 */
4246
		bo->map = ptr;
4246
		bo->map = ptr;
4247
		DBG(("%s: caching GTT vma for %d\n", __FUNCTION__, bo->handle));
4247
		DBG(("%s: caching GTT vma for %d\n", __FUNCTION__, bo->handle));
4248
	}
4248
	}
4249
 
4249
 
4250
	return ptr;
4250
	return ptr;
4251
}
4251
}
4252
 
4252
 
4253
void *kgem_bo_map(struct kgem *kgem, struct kgem_bo *bo)
4253
void *kgem_bo_map(struct kgem *kgem, struct kgem_bo *bo)
4254
{
4254
{
4255
	void *ptr;
4255
	void *ptr;
4256
 
4256
 
4257
	DBG(("%s: handle=%d, offset=%d, tiling=%d, map=%p, domain=%d\n", __FUNCTION__,
4257
	DBG(("%s: handle=%d, offset=%d, tiling=%d, map=%p, domain=%d\n", __FUNCTION__,
4258
	     bo->handle, bo->presumed_offset, bo->tiling, bo->map, bo->domain));
4258
	     bo->handle, bo->presumed_offset, bo->tiling, bo->map, bo->domain));
4259
 
4259
 
4260
	assert(bo->proxy == NULL);
4260
	assert(bo->proxy == NULL);
4261
	assert(list_is_empty(&bo->list));
4261
	assert(list_is_empty(&bo->list));
4262
	assert(!IS_USER_MAP(bo->map));
4262
	assert(!IS_USER_MAP(bo->map));
4263
	assert(bo->exec == NULL);
4263
	assert(bo->exec == NULL);
4264
	assert_tiling(kgem, bo);
4264
	assert_tiling(kgem, bo);
4265
 
4265
 
4266
	if (bo->tiling == I915_TILING_NONE && !bo->scanout &&
4266
	if (bo->tiling == I915_TILING_NONE && !bo->scanout &&
4267
	    (kgem->has_llc || bo->domain == DOMAIN_CPU)) {
4267
	    (kgem->has_llc || bo->domain == DOMAIN_CPU)) {
4268
		DBG(("%s: converting request for GTT map into CPU map\n",
4268
		DBG(("%s: converting request for GTT map into CPU map\n",
4269
		     __FUNCTION__));
4269
		     __FUNCTION__));
4270
		ptr = kgem_bo_map__cpu(kgem, bo);
4270
		ptr = kgem_bo_map__cpu(kgem, bo);
4271
		if (ptr)
4271
		if (ptr)
4272
			kgem_bo_sync__cpu(kgem, bo);
4272
			kgem_bo_sync__cpu(kgem, bo);
4273
		return ptr;
4273
		return ptr;
4274
	}
4274
	}
4275
 
4275
 
4276
	if (IS_CPU_MAP(bo->map))
4276
	if (IS_CPU_MAP(bo->map))
4277
		kgem_bo_release_map(kgem, bo);
4277
		kgem_bo_release_map(kgem, bo);
4278
 
4278
 
4279
	ptr = bo->map;
4279
	ptr = bo->map;
4280
	if (ptr == NULL) {
4280
	if (ptr == NULL) {
4281
		assert(kgem_bo_size(bo) <= kgem->aperture_mappable / 2);
4281
		assert(kgem_bo_size(bo) <= kgem->aperture_mappable / 2);
4282
		assert(kgem->gen != 021 || bo->tiling != I915_TILING_Y);
4282
		assert(kgem->gen != 021 || bo->tiling != I915_TILING_Y);
4283
 
4283
 
4284
		kgem_trim_vma_cache(kgem, MAP_GTT, bucket(bo));
4284
		kgem_trim_vma_cache(kgem, MAP_GTT, bucket(bo));
4285
 
4285
 
4286
		ptr = __kgem_bo_map__gtt(kgem, bo);
4286
		ptr = __kgem_bo_map__gtt(kgem, bo);
4287
		if (ptr == NULL)
4287
		if (ptr == NULL)
4288
			return NULL;
4288
			return NULL;
4289
 
4289
 
4290
		/* Cache this mapping to avoid the overhead of an
4290
		/* Cache this mapping to avoid the overhead of an
4291
		 * excruciatingly slow GTT pagefault. This is more an
4291
		 * excruciatingly slow GTT pagefault. This is more an
4292
		 * issue with compositing managers which need to frequently
4292
		 * issue with compositing managers which need to frequently
4293
		 * flush CPU damage to their GPU bo.
4293
		 * flush CPU damage to their GPU bo.
4294
		 */
4294
		 */
4295
		bo->map = ptr;
4295
		bo->map = ptr;
4296
		DBG(("%s: caching GTT vma for %d\n", __FUNCTION__, bo->handle));
4296
		DBG(("%s: caching GTT vma for %d\n", __FUNCTION__, bo->handle));
4297
		}
4297
		}
4298
 
4298
 
4299
	if (bo->domain != DOMAIN_GTT || FORCE_MMAP_SYNC & (1 << DOMAIN_GTT)) {
4299
	if (bo->domain != DOMAIN_GTT || FORCE_MMAP_SYNC & (1 << DOMAIN_GTT)) {
4300
		struct drm_i915_gem_set_domain set_domain;
4300
		struct drm_i915_gem_set_domain set_domain;
4301
 
4301
 
4302
		DBG(("%s: sync: needs_flush? %d, domain? %d, busy? %d\n", __FUNCTION__,
4302
		DBG(("%s: sync: needs_flush? %d, domain? %d, busy? %d\n", __FUNCTION__,
4303
		     bo->needs_flush, bo->domain, __kgem_busy(kgem, bo->handle)));
4303
		     bo->needs_flush, bo->domain, __kgem_busy(kgem, bo->handle)));
4304
 
4304
 
4305
		/* XXX use PROT_READ to avoid the write flush? */
4305
		/* XXX use PROT_READ to avoid the write flush? */
4306
 
4306
 
4307
		VG_CLEAR(set_domain);
4307
		VG_CLEAR(set_domain);
4308
		set_domain.handle = bo->handle;
4308
		set_domain.handle = bo->handle;
4309
		set_domain.read_domains = I915_GEM_DOMAIN_GTT;
4309
		set_domain.read_domains = I915_GEM_DOMAIN_GTT;
4310
		set_domain.write_domain = I915_GEM_DOMAIN_GTT;
4310
		set_domain.write_domain = I915_GEM_DOMAIN_GTT;
4311
		if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain) == 0) {
4311
		if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain) == 0) {
4312
			kgem_bo_retire(kgem, bo);
4312
			kgem_bo_retire(kgem, bo);
4313
			bo->domain = DOMAIN_GTT;
4313
			bo->domain = DOMAIN_GTT;
4314
			bo->gtt_dirty = true;
4314
			bo->gtt_dirty = true;
4315
		}
4315
		}
4316
		}
4316
		}
4317
 
4317
 
4318
	return ptr;
4318
	return ptr;
4319
}
4319
}
4320
 
4320
 
4321
void *kgem_bo_map__gtt(struct kgem *kgem, struct kgem_bo *bo)
4321
void *kgem_bo_map__gtt(struct kgem *kgem, struct kgem_bo *bo)
4322
{
4322
{
4323
	void *ptr;
4323
	void *ptr;
4324
 
4324
 
4325
	DBG(("%s: handle=%d, offset=%d, tiling=%d, map=%p, domain=%d\n", __FUNCTION__,
4325
	DBG(("%s: handle=%d, offset=%d, tiling=%d, map=%p, domain=%d\n", __FUNCTION__,
4326
	     bo->handle, bo->presumed_offset, bo->tiling, bo->map, bo->domain));
4326
	     bo->handle, bo->presumed_offset, bo->tiling, bo->map, bo->domain));
4327
 
4327
 
4328
	assert(bo->exec == NULL);
4328
	assert(bo->exec == NULL);
4329
	assert(list_is_empty(&bo->list));
4329
	assert(list_is_empty(&bo->list));
4330
	assert(!IS_USER_MAP(bo->map));
4330
	assert(!IS_USER_MAP(bo->map));
4331
	assert_tiling(kgem, bo);
4331
	assert_tiling(kgem, bo);
4332
 
4332
 
4333
	if (IS_CPU_MAP(bo->map))
4333
	if (IS_CPU_MAP(bo->map))
4334
		kgem_bo_release_map(kgem, bo);
4334
		kgem_bo_release_map(kgem, bo);
4335
 
4335
 
4336
	ptr = bo->map;
4336
	ptr = bo->map;
4337
	if (ptr == NULL) {
4337
	if (ptr == NULL) {
4338
		assert(bytes(bo) <= kgem->aperture_mappable / 4);
4338
		assert(bytes(bo) <= kgem->aperture_mappable / 4);
4339
 
4339
 
4340
		kgem_trim_vma_cache(kgem, MAP_GTT, bucket(bo));
4340
		kgem_trim_vma_cache(kgem, MAP_GTT, bucket(bo));
4341
 
4341
 
4342
		ptr = __kgem_bo_map__gtt(kgem, bo);
4342
		ptr = __kgem_bo_map__gtt(kgem, bo);
4343
		if (ptr == NULL)
4343
		if (ptr == NULL)
4344
			return NULL;
4344
			return NULL;
4345
 
4345
 
4346
		/* Cache this mapping to avoid the overhead of an
4346
		/* Cache this mapping to avoid the overhead of an
4347
		 * excruciatingly slow GTT pagefault. This is more an
4347
		 * excruciatingly slow GTT pagefault. This is more an
4348
		 * issue with compositing managers which need to frequently
4348
		 * issue with compositing managers which need to frequently
4349
		 * flush CPU damage to their GPU bo.
4349
		 * flush CPU damage to their GPU bo.
4350
		 */
4350
		 */
4351
		bo->map = ptr;
4351
		bo->map = ptr;
4352
		DBG(("%s: caching GTT vma for %d\n", __FUNCTION__, bo->handle));
4352
		DBG(("%s: caching GTT vma for %d\n", __FUNCTION__, bo->handle));
4353
	}
4353
	}
4354
 
4354
 
4355
	return ptr;
4355
	return ptr;
4356
}
4356
}
4357
 
4357
 
4358
void *kgem_bo_map__debug(struct kgem *kgem, struct kgem_bo *bo)
4358
void *kgem_bo_map__debug(struct kgem *kgem, struct kgem_bo *bo)
4359
{
4359
{
4360
	if (bo->map)
4360
	if (bo->map)
4361
		return MAP(bo->map);
4361
		return MAP(bo->map);
4362
 
4362
 
4363
	kgem_trim_vma_cache(kgem, MAP_GTT, bucket(bo));
4363
	kgem_trim_vma_cache(kgem, MAP_GTT, bucket(bo));
4364
	return bo->map = __kgem_bo_map__gtt(kgem, bo);
4364
	return bo->map = __kgem_bo_map__gtt(kgem, bo);
4365
}
4365
}
4366
 
4366
 
4367
void *kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo)
4367
void *kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo)
4368
{
4368
{
4369
	struct drm_i915_gem_mmap mmap_arg;
4369
	struct drm_i915_gem_mmap mmap_arg;
4370
 
4370
 
4371
	DBG(("%s(handle=%d, size=%d, mapped? %d)\n",
4371
	DBG(("%s(handle=%d, size=%d, mapped? %d)\n",
4372
	     __FUNCTION__, bo->handle, bytes(bo), (int)__MAP_TYPE(bo->map)));
4372
	     __FUNCTION__, bo->handle, bytes(bo), (int)__MAP_TYPE(bo->map)));
4373
	assert(!bo->purged);
4373
	assert(!bo->purged);
4374
	assert(list_is_empty(&bo->list));
4374
	assert(list_is_empty(&bo->list));
4375
	assert(bo->proxy == NULL);
4375
	assert(bo->proxy == NULL);
4376
 
4376
 
4377
	if (IS_CPU_MAP(bo->map))
4377
	if (IS_CPU_MAP(bo->map))
4378
		return MAP(bo->map);
4378
		return MAP(bo->map);
4379
 
4379
 
4380
	if (bo->map)
4380
	if (bo->map)
4381
		kgem_bo_release_map(kgem, bo);
4381
		kgem_bo_release_map(kgem, bo);
4382
 
4382
 
4383
	kgem_trim_vma_cache(kgem, MAP_CPU, bucket(bo));
4383
	kgem_trim_vma_cache(kgem, MAP_CPU, bucket(bo));
4384
 
4384
 
4385
retry:
4385
retry:
4386
	VG_CLEAR(mmap_arg);
4386
	VG_CLEAR(mmap_arg);
4387
	mmap_arg.handle = bo->handle;
4387
	mmap_arg.handle = bo->handle;
4388
	mmap_arg.offset = 0;
4388
	mmap_arg.offset = 0;
4389
	mmap_arg.size = bytes(bo);
4389
	mmap_arg.size = bytes(bo);
4390
	if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_MMAP, &mmap_arg)) {
4390
	if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_MMAP, &mmap_arg)) {
4391
 
4391
 
4392
		if (__kgem_throttle_retire(kgem, 0))
4392
		if (__kgem_throttle_retire(kgem, 0))
4393
			goto retry;
4393
			goto retry;
4394
 
4394
 
4395
		if (kgem->need_expire) {
4395
		if (kgem->need_expire) {
4396
			kgem_cleanup_cache(kgem);
4396
			kgem_cleanup_cache(kgem);
4397
			goto retry;
4397
			goto retry;
4398
		}
4398
		}
4399
 
4399
 
4400
		ErrorF("%s: failed to mmap handle=%d, %d bytes, into CPU domain\n",
4400
		ErrorF("%s: failed to mmap handle=%d, %d bytes, into CPU domain\n",
4401
		       __FUNCTION__, bo->handle, bytes(bo));
4401
		       __FUNCTION__, bo->handle, bytes(bo));
4402
		return NULL;
4402
		return NULL;
4403
	}
4403
	}
4404
 
4404
 
4405
	VG(VALGRIND_MAKE_MEM_DEFINED(mmap_arg.addr_ptr, bytes(bo)));
4405
	VG(VALGRIND_MAKE_MEM_DEFINED(mmap_arg.addr_ptr, bytes(bo)));
4406
 
4406
 
4407
	DBG(("%s: caching CPU vma for %d\n", __FUNCTION__, bo->handle));
4407
	DBG(("%s: caching CPU vma for %d\n", __FUNCTION__, bo->handle));
4408
	bo->map = MAKE_CPU_MAP(mmap_arg.addr_ptr);
4408
	bo->map = MAKE_CPU_MAP(mmap_arg.addr_ptr);
4409
	return (void *)(uintptr_t)mmap_arg.addr_ptr;
4409
	return (void *)(uintptr_t)mmap_arg.addr_ptr;
4410
}
4410
}
4411
 
4411
 
4412
void *__kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo)
4412
void *__kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo)
4413
{
4413
{
4414
	struct drm_i915_gem_mmap mmap_arg;
4414
	struct drm_i915_gem_mmap mmap_arg;
4415
 
4415
 
4416
	DBG(("%s(handle=%d, size=%d, mapped? %d)\n",
4416
	DBG(("%s(handle=%d, size=%d, mapped? %d)\n",
4417
	     __FUNCTION__, bo->handle, bytes(bo), (int)__MAP_TYPE(bo->map)));
4417
	     __FUNCTION__, bo->handle, bytes(bo), (int)__MAP_TYPE(bo->map)));
4418
        assert(bo->refcnt);
4418
        assert(bo->refcnt);
4419
	assert(!bo->purged);
4419
	assert(!bo->purged);
4420
	assert(list_is_empty(&bo->list));
4420
	assert(list_is_empty(&bo->list));
4421
	assert(bo->proxy == NULL);
4421
	assert(bo->proxy == NULL);
4422
 
4422
 
4423
	if (IS_CPU_MAP(bo->map))
4423
	if (IS_CPU_MAP(bo->map))
4424
		return MAP(bo->map);
4424
		return MAP(bo->map);
4425
 
4425
 
4426
retry:
4426
retry:
4427
	VG_CLEAR(mmap_arg);
4427
	VG_CLEAR(mmap_arg);
4428
	mmap_arg.handle = bo->handle;
4428
	mmap_arg.handle = bo->handle;
4429
	mmap_arg.offset = 0;
4429
	mmap_arg.offset = 0;
4430
	mmap_arg.size = bytes(bo);
4430
	mmap_arg.size = bytes(bo);
4431
	if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_MMAP, &mmap_arg)) {
4431
	if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_MMAP, &mmap_arg)) {
4432
		int err = errno;
4432
		int err = errno;
4433
 
4433
 
4434
		assert(err != EINVAL);
4434
		assert(err != EINVAL);
4435
 
4435
 
4436
		if (__kgem_throttle_retire(kgem, 0))
4436
		if (__kgem_throttle_retire(kgem, 0))
4437
			goto retry;
4437
			goto retry;
4438
 
4438
 
4439
		if (kgem->need_expire) {
4439
		if (kgem->need_expire) {
4440
			kgem_cleanup_cache(kgem);
4440
			kgem_cleanup_cache(kgem);
4441
			goto retry;
4441
			goto retry;
4442
		}
4442
		}
4443
 
4443
 
4444
		ErrorF("%s: failed to mmap handle=%d, %d bytes, into CPU domain: %d\n",
4444
		ErrorF("%s: failed to mmap handle=%d, %d bytes, into CPU domain: %d\n",
4445
		       __FUNCTION__, bo->handle, bytes(bo), err);
4445
		       __FUNCTION__, bo->handle, bytes(bo), err);
4446
		return NULL;
4446
		return NULL;
4447
	}
4447
	}
4448
 
4448
 
4449
	VG(VALGRIND_MAKE_MEM_DEFINED(mmap_arg.addr_ptr, bytes(bo)));
4449
	VG(VALGRIND_MAKE_MEM_DEFINED(mmap_arg.addr_ptr, bytes(bo)));
4450
	if (bo->map && bo->domain == DOMAIN_CPU) {
4450
	if (bo->map && bo->domain == DOMAIN_CPU) {
4451
		DBG(("%s: discarding GTT vma for %d\n", __FUNCTION__, bo->handle));
4451
		DBG(("%s: discarding GTT vma for %d\n", __FUNCTION__, bo->handle));
4452
		kgem_bo_release_map(kgem, bo);
4452
		kgem_bo_release_map(kgem, bo);
4453
	}
4453
	}
4454
	if (bo->map == NULL) {
4454
	if (bo->map == NULL) {
4455
		DBG(("%s: caching CPU vma for %d\n", __FUNCTION__, bo->handle));
4455
		DBG(("%s: caching CPU vma for %d\n", __FUNCTION__, bo->handle));
4456
		bo->map = MAKE_CPU_MAP(mmap_arg.addr_ptr);
4456
		bo->map = MAKE_CPU_MAP(mmap_arg.addr_ptr);
4457
	}
4457
	}
4458
	return (void *)(uintptr_t)mmap_arg.addr_ptr;
4458
	return (void *)(uintptr_t)mmap_arg.addr_ptr;
4459
}
4459
}
4460
void kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo *bo)
4460
void kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo *bo)
4461
{
4461
{
4462
	DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
4462
	DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
4463
	assert(!bo->scanout);
4463
	assert(!bo->scanout);
4464
	kgem_bo_submit(kgem, bo);
4464
	kgem_bo_submit(kgem, bo);
4465
 
4465
 
4466
	/* SHM pixmaps use proxies for subpage offsets */
4466
	/* SHM pixmaps use proxies for subpage offsets */
4467
	assert(!bo->purged);
4467
	assert(!bo->purged);
4468
	while (bo->proxy)
4468
	while (bo->proxy)
4469
		bo = bo->proxy;
4469
		bo = bo->proxy;
4470
	assert(!bo->purged);
4470
	assert(!bo->purged);
4471
 
4471
 
4472
	if (bo->domain != DOMAIN_CPU || FORCE_MMAP_SYNC & (1 << DOMAIN_CPU)) {
4472
	if (bo->domain != DOMAIN_CPU || FORCE_MMAP_SYNC & (1 << DOMAIN_CPU)) {
4473
		struct drm_i915_gem_set_domain set_domain;
4473
		struct drm_i915_gem_set_domain set_domain;
4474
 
4474
 
4475
		DBG(("%s: SYNC: handle=%d, needs_flush? %d, domain? %d, busy? %d\n",
4475
		DBG(("%s: SYNC: handle=%d, needs_flush? %d, domain? %d, busy? %d\n",
4476
		     __FUNCTION__, bo->handle,
4476
		     __FUNCTION__, bo->handle,
4477
		     bo->needs_flush, bo->domain,
4477
		     bo->needs_flush, bo->domain,
4478
		     __kgem_busy(kgem, bo->handle)));
4478
		     __kgem_busy(kgem, bo->handle)));
4479
 
4479
 
4480
		VG_CLEAR(set_domain);
4480
		VG_CLEAR(set_domain);
4481
		set_domain.handle = bo->handle;
4481
		set_domain.handle = bo->handle;
4482
		set_domain.read_domains = I915_GEM_DOMAIN_CPU;
4482
		set_domain.read_domains = I915_GEM_DOMAIN_CPU;
4483
		set_domain.write_domain = I915_GEM_DOMAIN_CPU;
4483
		set_domain.write_domain = I915_GEM_DOMAIN_CPU;
4484
 
4484
 
4485
		if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain) == 0) {
4485
		if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain) == 0) {
4486
			kgem_bo_retire(kgem, bo);
4486
			kgem_bo_retire(kgem, bo);
4487
			bo->domain = DOMAIN_CPU;
4487
			bo->domain = DOMAIN_CPU;
4488
		}
4488
		}
4489
	}
4489
	}
4490
}
4490
}
4491
 
4491
 
4492
void kgem_clear_dirty(struct kgem *kgem)
4492
void kgem_clear_dirty(struct kgem *kgem)
4493
{
4493
{
4494
	struct list * const buffers = &kgem->next_request->buffers;
4494
	struct list * const buffers = &kgem->next_request->buffers;
4495
	struct kgem_bo *bo;
4495
	struct kgem_bo *bo;
4496
 
4496
 
4497
	list_for_each_entry(bo, buffers, request) {
4497
	list_for_each_entry(bo, buffers, request) {
4498
		if (!bo->gpu_dirty)
4498
		if (!bo->gpu_dirty)
4499
			break;
4499
			break;
4500
 
4500
 
4501
		bo->gpu_dirty = false;
4501
		bo->gpu_dirty = false;
4502
	}
4502
	}
4503
}
4503
}
4504
 
4504
 
4505
struct kgem_bo *kgem_create_proxy(struct kgem *kgem,
4505
struct kgem_bo *kgem_create_proxy(struct kgem *kgem,
4506
				  struct kgem_bo *target,
4506
				  struct kgem_bo *target,
4507
				  int offset, int length)
4507
				  int offset, int length)
4508
{
4508
{
4509
	struct kgem_bo *bo;
4509
	struct kgem_bo *bo;
4510
 
4510
 
4511
	DBG(("%s: target handle=%d [proxy? %d], offset=%d, length=%d, io=%d\n",
4511
	DBG(("%s: target handle=%d [proxy? %d], offset=%d, length=%d, io=%d\n",
4512
	     __FUNCTION__, target->handle, target->proxy ? target->proxy->delta : -1,
4512
	     __FUNCTION__, target->handle, target->proxy ? target->proxy->delta : -1,
4513
	     offset, length, target->io));
4513
	     offset, length, target->io));
4514
 
4514
 
4515
	bo = __kgem_bo_alloc(target->handle, length);
4515
	bo = __kgem_bo_alloc(target->handle, length);
4516
	if (bo == NULL)
4516
	if (bo == NULL)
4517
		return NULL;
4517
		return NULL;
4518
 
4518
 
4519
	bo->unique_id = kgem_get_unique_id(kgem);
4519
	bo->unique_id = kgem_get_unique_id(kgem);
4520
	bo->reusable = false;
4520
	bo->reusable = false;
4521
	bo->size.bytes = length;
4521
	bo->size.bytes = length;
4522
 
4522
 
4523
	bo->io = target->io && target->proxy == NULL;
4523
	bo->io = target->io && target->proxy == NULL;
4524
	bo->gpu_dirty = target->gpu_dirty;
4524
	bo->gpu_dirty = target->gpu_dirty;
4525
	bo->tiling = target->tiling;
4525
	bo->tiling = target->tiling;
4526
	bo->pitch = target->pitch;
4526
	bo->pitch = target->pitch;
4527
	bo->flush = target->flush;
4527
	bo->flush = target->flush;
4528
	bo->snoop = target->snoop;
4528
	bo->snoop = target->snoop;
4529
 
4529
 
4530
	assert(!bo->scanout);
4530
	assert(!bo->scanout);
4531
	bo->proxy = kgem_bo_reference(target);
4531
	bo->proxy = kgem_bo_reference(target);
4532
	bo->delta = offset;
4532
	bo->delta = offset;
4533
 
4533
 
4534
	if (target->exec) {
4534
	if (target->exec) {
4535
		list_move_tail(&bo->request, &kgem->next_request->buffers);
4535
		list_move_tail(&bo->request, &kgem->next_request->buffers);
4536
		bo->exec = &_kgem_dummy_exec;
4536
		bo->exec = &_kgem_dummy_exec;
4537
	}
4537
	}
4538
	bo->rq = target->rq;
4538
	bo->rq = target->rq;
4539
 
4539
 
4540
	return bo;
4540
	return bo;
4541
}
4541
}
4542
 
4542
 
4543
#if 0
4543
#if 0
4544
static struct kgem_buffer *
4544
static struct kgem_buffer *
4545
buffer_alloc(void)
4545
buffer_alloc(void)
4546
{
4546
{
4547
	struct kgem_buffer *bo;
4547
	struct kgem_buffer *bo;
4548
 
4548
 
4549
	bo = malloc(sizeof(*bo));
4549
	bo = malloc(sizeof(*bo));
4550
	if (bo == NULL)
4550
	if (bo == NULL)
4551
		return NULL;
4551
		return NULL;
4552
 
4552
 
4553
	bo->mem = NULL;
4553
	bo->mem = NULL;
4554
	bo->need_io = false;
4554
	bo->need_io = false;
4555
	bo->mmapped = true;
4555
	bo->mmapped = true;
4556
 
4556
 
4557
	return bo;
4557
	return bo;
4558
}
4558
}
4559
 
4559
 
4560
static struct kgem_buffer *
4560
static struct kgem_buffer *
4561
buffer_alloc_with_data(int num_pages)
4561
buffer_alloc_with_data(int num_pages)
4562
{
4562
{
4563
	struct kgem_buffer *bo;
4563
	struct kgem_buffer *bo;
4564
 
4564
 
4565
	bo = malloc(sizeof(*bo) + 2*UPLOAD_ALIGNMENT + num_pages * PAGE_SIZE);
4565
	bo = malloc(sizeof(*bo) + 2*UPLOAD_ALIGNMENT + num_pages * PAGE_SIZE);
4566
	if (bo == NULL)
4566
	if (bo == NULL)
4567
		return NULL;
4567
		return NULL;
4568
 
4568
 
4569
	bo->mem = (void *)ALIGN((uintptr_t)bo + sizeof(*bo), UPLOAD_ALIGNMENT);
4569
	bo->mem = (void *)ALIGN((uintptr_t)bo + sizeof(*bo), UPLOAD_ALIGNMENT);
4570
	bo->mmapped = false;
4570
	bo->mmapped = false;
4571
	return bo;
4571
	return bo;
4572
}
4572
}
4573
 
4573
 
4574
static inline bool
4574
static inline bool
4575
use_snoopable_buffer(struct kgem *kgem, uint32_t flags)
4575
use_snoopable_buffer(struct kgem *kgem, uint32_t flags)
4576
{
4576
{
4577
	if ((flags & KGEM_BUFFER_WRITE) == 0)
4577
	if ((flags & KGEM_BUFFER_WRITE) == 0)
4578
		return kgem->gen >= 030;
4578
		return kgem->gen >= 030;
4579
 
4579
 
4580
	return true;
4580
	return true;
4581
}
4581
}
4582
 
4582
 
4583
static void
4583
static void
4584
init_buffer_from_bo(struct kgem_buffer *bo, struct kgem_bo *old)
4584
init_buffer_from_bo(struct kgem_buffer *bo, struct kgem_bo *old)
4585
{
4585
{
4586
	DBG(("%s: reusing handle=%d for buffer\n",
4586
	DBG(("%s: reusing handle=%d for buffer\n",
4587
	     __FUNCTION__, old->handle));
4587
	     __FUNCTION__, old->handle));
4588
 
4588
 
4589
	assert(old->proxy == NULL);
4589
	assert(old->proxy == NULL);
4590
 
4590
 
4591
	memcpy(&bo->base, old, sizeof(*old));
4591
	memcpy(&bo->base, old, sizeof(*old));
4592
	if (old->rq)
4592
	if (old->rq)
4593
		list_replace(&old->request, &bo->base.request);
4593
		list_replace(&old->request, &bo->base.request);
4594
	else
4594
	else
4595
		list_init(&bo->base.request);
4595
		list_init(&bo->base.request);
4596
	list_replace(&old->vma, &bo->base.vma);
4596
	list_replace(&old->vma, &bo->base.vma);
4597
	list_init(&bo->base.list);
4597
	list_init(&bo->base.list);
4598
	free(old);
4598
	free(old);
4599
 
4599
 
4600
	assert(bo->base.tiling == I915_TILING_NONE);
4600
	assert(bo->base.tiling == I915_TILING_NONE);
4601
 
4601
 
4602
	bo->base.refcnt = 1;
4602
	bo->base.refcnt = 1;
4603
}
4603
}
4604
 
4604
 
4605
static struct kgem_buffer *
4605
static struct kgem_buffer *
4606
search_snoopable_buffer(struct kgem *kgem, unsigned alloc)
4606
search_snoopable_buffer(struct kgem *kgem, unsigned alloc)
4607
{
4607
{
4608
	struct kgem_buffer *bo;
4608
	struct kgem_buffer *bo;
4609
	struct kgem_bo *old;
4609
	struct kgem_bo *old;
4610
 
4610
 
4611
	old = search_snoop_cache(kgem, alloc, 0);
4611
	old = search_snoop_cache(kgem, alloc, 0);
4612
	if (old) {
4612
	if (old) {
4613
		if (!old->io) {
4613
		if (!old->io) {
4614
			bo = buffer_alloc();
4614
			bo = buffer_alloc();
4615
			if (bo == NULL)
4615
			if (bo == NULL)
4616
				return NULL;
4616
				return NULL;
4617
 
4617
 
4618
			init_buffer_from_bo(bo, old);
4618
			init_buffer_from_bo(bo, old);
4619
		} else {
4619
		} else {
4620
			bo = (struct kgem_buffer *)old;
4620
			bo = (struct kgem_buffer *)old;
4621
			bo->base.refcnt = 1;
4621
			bo->base.refcnt = 1;
4622
		}
4622
		}
4623
 
4623
 
4624
		DBG(("%s: created CPU handle=%d for buffer, size %d\n",
4624
		DBG(("%s: created CPU handle=%d for buffer, size %d\n",
4625
		     __FUNCTION__, bo->base.handle, num_pages(&bo->base)));
4625
		     __FUNCTION__, bo->base.handle, num_pages(&bo->base)));
4626
 
4626
 
4627
		assert(bo->base.snoop);
4627
		assert(bo->base.snoop);
4628
		assert(bo->base.tiling == I915_TILING_NONE);
4628
		assert(bo->base.tiling == I915_TILING_NONE);
4629
		assert(num_pages(&bo->base) >= alloc);
4629
		assert(num_pages(&bo->base) >= alloc);
4630
		assert(bo->mmapped == true);
4630
		assert(bo->mmapped == true);
4631
		assert(bo->need_io == false);
4631
		assert(bo->need_io == false);
4632
 
4632
 
4633
		bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
4633
		bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
4634
		if (bo->mem == NULL) {
4634
		if (bo->mem == NULL) {
4635
			bo->base.refcnt = 0;
4635
			bo->base.refcnt = 0;
4636
			kgem_bo_free(kgem, &bo->base);
4636
			kgem_bo_free(kgem, &bo->base);
4637
			bo = NULL;
4637
			bo = NULL;
4638
		}
4638
		}
4639
 
4639
 
4640
		return bo;
4640
		return bo;
4641
	}
4641
	}
4642
 
4642
 
4643
	return NULL;
4643
	return NULL;
4644
}
4644
}
4645
 
4645
 
4646
static struct kgem_buffer *
4646
static struct kgem_buffer *
4647
create_snoopable_buffer(struct kgem *kgem, unsigned alloc)
4647
create_snoopable_buffer(struct kgem *kgem, unsigned alloc)
4648
{
4648
{
4649
	struct kgem_buffer *bo;
4649
	struct kgem_buffer *bo;
4650
	uint32_t handle;
4650
	uint32_t handle;
4651
 
4651
 
4652
	if (kgem->has_llc) {
4652
	if (kgem->has_llc) {
4653
		struct kgem_bo *old;
4653
		struct kgem_bo *old;
4654
 
4654
 
4655
		bo = buffer_alloc();
4655
		bo = buffer_alloc();
4656
		if (bo == NULL)
4656
		if (bo == NULL)
4657
			return NULL;
4657
			return NULL;
4658
 
4658
 
4659
		old = search_linear_cache(kgem, alloc,
4659
		old = search_linear_cache(kgem, alloc,
4660
					 CREATE_INACTIVE | CREATE_CPU_MAP | CREATE_EXACT);
4660
					 CREATE_INACTIVE | CREATE_CPU_MAP | CREATE_EXACT);
4661
		if (old) {
4661
		if (old) {
4662
			init_buffer_from_bo(bo, old);
4662
			init_buffer_from_bo(bo, old);
4663
		} else {
4663
		} else {
4664
			handle = gem_create(kgem->fd, alloc);
4664
			handle = gem_create(kgem->fd, alloc);
4665
			if (handle == 0) {
4665
			if (handle == 0) {
4666
				free(bo);
4666
				free(bo);
4667
				return NULL;
4667
				return NULL;
4668
			}
4668
			}
4669
 
4669
 
4670
			debug_alloc(kgem, alloc);
4670
			debug_alloc(kgem, alloc);
4671
			__kgem_bo_init(&bo->base, handle, alloc);
4671
			__kgem_bo_init(&bo->base, handle, alloc);
4672
			DBG(("%s: created CPU (LLC) handle=%d for buffer, size %d\n",
4672
			DBG(("%s: created CPU (LLC) handle=%d for buffer, size %d\n",
4673
			     __FUNCTION__, bo->base.handle, alloc));
4673
			     __FUNCTION__, bo->base.handle, alloc));
4674
		}
4674
		}
4675
 
4675
 
4676
		assert(bo->base.refcnt == 1);
4676
		assert(bo->base.refcnt == 1);
4677
		assert(bo->mmapped == true);
4677
		assert(bo->mmapped == true);
4678
		assert(bo->need_io == false);
4678
		assert(bo->need_io == false);
4679
 
4679
 
4680
		bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
4680
		bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
4681
		if (bo->mem != NULL)
4681
		if (bo->mem != NULL)
4682
			return bo;
4682
			return bo;
4683
 
4683
 
4684
		bo->base.refcnt = 0; /* for valgrind */
4684
		bo->base.refcnt = 0; /* for valgrind */
4685
		kgem_bo_free(kgem, &bo->base);
4685
		kgem_bo_free(kgem, &bo->base);
4686
	}
4686
	}
4687
 
4687
 
4688
	if (kgem->has_caching) {
4688
	if (kgem->has_caching) {
4689
		struct kgem_bo *old;
4689
		struct kgem_bo *old;
4690
 
4690
 
4691
		bo = buffer_alloc();
4691
		bo = buffer_alloc();
4692
		if (bo == NULL)
4692
		if (bo == NULL)
4693
			return NULL;
4693
			return NULL;
4694
 
4694
 
4695
		old = search_linear_cache(kgem, alloc,
4695
		old = search_linear_cache(kgem, alloc,
4696
					 CREATE_INACTIVE | CREATE_CPU_MAP | CREATE_EXACT);
4696
					 CREATE_INACTIVE | CREATE_CPU_MAP | CREATE_EXACT);
4697
		if (old) {
4697
		if (old) {
4698
			init_buffer_from_bo(bo, old);
4698
			init_buffer_from_bo(bo, old);
4699
		} else {
4699
		} else {
4700
			handle = gem_create(kgem->fd, alloc);
4700
			handle = gem_create(kgem->fd, alloc);
4701
			if (handle == 0) {
4701
			if (handle == 0) {
4702
				free(bo);
4702
				free(bo);
4703
				return NULL;
4703
				return NULL;
4704
			}
4704
			}
4705
 
4705
 
4706
			debug_alloc(kgem, alloc);
4706
			debug_alloc(kgem, alloc);
4707
			__kgem_bo_init(&bo->base, handle, alloc);
4707
			__kgem_bo_init(&bo->base, handle, alloc);
4708
			DBG(("%s: created CPU handle=%d for buffer, size %d\n",
4708
			DBG(("%s: created CPU handle=%d for buffer, size %d\n",
4709
			     __FUNCTION__, bo->base.handle, alloc));
4709
			     __FUNCTION__, bo->base.handle, alloc));
4710
		}
4710
		}
4711
 
4711
 
4712
		assert(bo->base.refcnt == 1);
4712
		assert(bo->base.refcnt == 1);
4713
		assert(bo->mmapped == true);
4713
		assert(bo->mmapped == true);
4714
		assert(bo->need_io == false);
4714
		assert(bo->need_io == false);
4715
 
4715
 
4716
		if (!gem_set_caching(kgem->fd, bo->base.handle, SNOOPED))
4716
		if (!gem_set_caching(kgem->fd, bo->base.handle, SNOOPED))
4717
			goto free_caching;
4717
			goto free_caching;
4718
 
4718
 
4719
		bo->base.snoop = true;
4719
		bo->base.snoop = true;
4720
 
4720
 
4721
		bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
4721
		bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
4722
		if (bo->mem == NULL)
4722
		if (bo->mem == NULL)
4723
			goto free_caching;
4723
			goto free_caching;
4724
 
4724
 
4725
		return bo;
4725
		return bo;
4726
 
4726
 
4727
free_caching:
4727
free_caching:
4728
		bo->base.refcnt = 0; /* for valgrind */
4728
		bo->base.refcnt = 0; /* for valgrind */
4729
		kgem_bo_free(kgem, &bo->base);
4729
		kgem_bo_free(kgem, &bo->base);
4730
	}
4730
	}
4731
 
4731
 
4732
	if (kgem->has_userptr) {
4732
	if (kgem->has_userptr) {
4733
		bo = buffer_alloc();
4733
		bo = buffer_alloc();
4734
		if (bo == NULL)
4734
		if (bo == NULL)
4735
			return NULL;
4735
			return NULL;
4736
 
4736
 
4737
		//if (posix_memalign(&ptr, 64, ALIGN(size, 64)))
4737
		//if (posix_memalign(&ptr, 64, ALIGN(size, 64)))
4738
		if (posix_memalign(&bo->mem, PAGE_SIZE, alloc * PAGE_SIZE)) {
4738
		if (posix_memalign(&bo->mem, PAGE_SIZE, alloc * PAGE_SIZE)) {
4739
			free(bo);
4739
			free(bo);
4740
			return NULL;
4740
			return NULL;
4741
		}
4741
		}
4742
 
4742
 
4743
		handle = gem_userptr(kgem->fd, bo->mem, alloc * PAGE_SIZE, false);
4743
		handle = gem_userptr(kgem->fd, bo->mem, alloc * PAGE_SIZE, false);
4744
		if (handle == 0) {
4744
		if (handle == 0) {
4745
			free(bo->mem);
4745
			free(bo->mem);
4746
			free(bo);
4746
			free(bo);
4747
			return NULL;
4747
			return NULL;
4748
		}
4748
		}
4749
 
4749
 
4750
		debug_alloc(kgem, alloc);
4750
		debug_alloc(kgem, alloc);
4751
		__kgem_bo_init(&bo->base, handle, alloc);
4751
		__kgem_bo_init(&bo->base, handle, alloc);
4752
		DBG(("%s: created snoop handle=%d for buffer\n",
4752
		DBG(("%s: created snoop handle=%d for buffer\n",
4753
		     __FUNCTION__, bo->base.handle));
4753
		     __FUNCTION__, bo->base.handle));
4754
 
4754
 
4755
		assert(bo->mmapped == true);
4755
		assert(bo->mmapped == true);
4756
		assert(bo->need_io == false);
4756
		assert(bo->need_io == false);
4757
 
4757
 
4758
		bo->base.refcnt = 1;
4758
		bo->base.refcnt = 1;
4759
		bo->base.snoop = true;
4759
		bo->base.snoop = true;
4760
		bo->base.map = MAKE_USER_MAP(bo->mem);
4760
		bo->base.map = MAKE_USER_MAP(bo->mem);
4761
 
4761
 
4762
		return bo;
4762
		return bo;
4763
	}
4763
	}
4764
 
4764
 
4765
	return NULL;
4765
	return NULL;
4766
}
4766
}
4767
 
4767
 
4768
struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
4768
struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
4769
				   uint32_t size, uint32_t flags,
4769
				   uint32_t size, uint32_t flags,
4770
				   void **ret)
4770
				   void **ret)
4771
{
4771
{
4772
	struct kgem_buffer *bo;
4772
	struct kgem_buffer *bo;
4773
	unsigned offset, alloc;
4773
	unsigned offset, alloc;
4774
	struct kgem_bo *old;
4774
	struct kgem_bo *old;
4775
 
4775
 
4776
	DBG(("%s: size=%d, flags=%x [write?=%d, inplace?=%d, last?=%d]\n",
4776
	DBG(("%s: size=%d, flags=%x [write?=%d, inplace?=%d, last?=%d]\n",
4777
	     __FUNCTION__, size, flags,
4777
	     __FUNCTION__, size, flags,
4778
	     !!(flags & KGEM_BUFFER_WRITE),
4778
	     !!(flags & KGEM_BUFFER_WRITE),
4779
	     !!(flags & KGEM_BUFFER_INPLACE),
4779
	     !!(flags & KGEM_BUFFER_INPLACE),
4780
	     !!(flags & KGEM_BUFFER_LAST)));
4780
	     !!(flags & KGEM_BUFFER_LAST)));
4781
	assert(size);
4781
	assert(size);
4782
	/* we should never be asked to create anything TOO large */
4782
	/* we should never be asked to create anything TOO large */
4783
	assert(size <= kgem->max_object_size);
4783
	assert(size <= kgem->max_object_size);
4784
 
4784
 
4785
#if !DBG_NO_UPLOAD_CACHE
4785
#if !DBG_NO_UPLOAD_CACHE
4786
	list_for_each_entry(bo, &kgem->batch_buffers, base.list) {
4786
	list_for_each_entry(bo, &kgem->batch_buffers, base.list) {
4787
		assert(bo->base.io);
4787
		assert(bo->base.io);
4788
		assert(bo->base.refcnt >= 1);
4788
		assert(bo->base.refcnt >= 1);
4789
 
4789
 
4790
		/* We can reuse any write buffer which we can fit */
4790
		/* We can reuse any write buffer which we can fit */
4791
		if (flags == KGEM_BUFFER_LAST &&
4791
		if (flags == KGEM_BUFFER_LAST &&
4792
		    bo->write == KGEM_BUFFER_WRITE &&
4792
		    bo->write == KGEM_BUFFER_WRITE &&
4793
		    bo->base.refcnt == 1 && !bo->mmapped &&
4793
		    bo->base.refcnt == 1 && !bo->mmapped &&
4794
		    size <= bytes(&bo->base)) {
4794
		    size <= bytes(&bo->base)) {
4795
			DBG(("%s: reusing write buffer for read of %d bytes? used=%d, total=%d\n",
4795
			DBG(("%s: reusing write buffer for read of %d bytes? used=%d, total=%d\n",
4796
			     __FUNCTION__, size, bo->used, bytes(&bo->base)));
4796
			     __FUNCTION__, size, bo->used, bytes(&bo->base)));
4797
			gem_write(kgem->fd, bo->base.handle,
4797
			gem_write(kgem->fd, bo->base.handle,
4798
				  0, bo->used, bo->mem);
4798
				  0, bo->used, bo->mem);
4799
			kgem_buffer_release(kgem, bo);
4799
			kgem_buffer_release(kgem, bo);
4800
			bo->need_io = 0;
4800
			bo->need_io = 0;
4801
			bo->write = 0;
4801
			bo->write = 0;
4802
			offset = 0;
4802
			offset = 0;
4803
			bo->used = size;
4803
			bo->used = size;
4804
			goto done;
4804
			goto done;
4805
		}
4805
		}
4806
 
4806
 
4807
		if (flags & KGEM_BUFFER_WRITE) {
4807
		if (flags & KGEM_BUFFER_WRITE) {
4808
			if ((bo->write & KGEM_BUFFER_WRITE) == 0 ||
4808
			if ((bo->write & KGEM_BUFFER_WRITE) == 0 ||
4809
			    (((bo->write & ~flags) & KGEM_BUFFER_INPLACE) &&
4809
			    (((bo->write & ~flags) & KGEM_BUFFER_INPLACE) &&
4810
			     !bo->base.snoop)) {
4810
			     !bo->base.snoop)) {
4811
				DBG(("%s: skip write %x buffer, need %x\n",
4811
				DBG(("%s: skip write %x buffer, need %x\n",
4812
				     __FUNCTION__, bo->write, flags));
4812
				     __FUNCTION__, bo->write, flags));
4813
				continue;
4813
				continue;
4814
			}
4814
			}
4815
			assert(bo->mmapped || bo->need_io);
4815
			assert(bo->mmapped || bo->need_io);
4816
		} else {
4816
		} else {
4817
			if (bo->write & KGEM_BUFFER_WRITE) {
4817
			if (bo->write & KGEM_BUFFER_WRITE) {
4818
				DBG(("%s: skip write %x buffer, need %x\n",
4818
				DBG(("%s: skip write %x buffer, need %x\n",
4819
				     __FUNCTION__, bo->write, flags));
4819
				     __FUNCTION__, bo->write, flags));
4820
				continue;
4820
				continue;
4821
			}
4821
			}
4822
		}
4822
		}
4823
 
4823
 
4824
		if (bo->used + size <= bytes(&bo->base)) {
4824
		if (bo->used + size <= bytes(&bo->base)) {
4825
			DBG(("%s: reusing buffer? used=%d + size=%d, total=%d\n",
4825
			DBG(("%s: reusing buffer? used=%d + size=%d, total=%d\n",
4826
			     __FUNCTION__, bo->used, size, bytes(&bo->base)));
4826
			     __FUNCTION__, bo->used, size, bytes(&bo->base)));
4827
			offset = bo->used;
4827
			offset = bo->used;
4828
			bo->used += size;
4828
			bo->used += size;
4829
			goto done;
4829
			goto done;
4830
		}
4830
		}
4831
	}
4831
	}
4832
 
4832
 
4833
	if (flags & KGEM_BUFFER_WRITE) {
4833
	if (flags & KGEM_BUFFER_WRITE) {
4834
		list_for_each_entry(bo, &kgem->active_buffers, base.list) {
4834
		list_for_each_entry(bo, &kgem->active_buffers, base.list) {
4835
			assert(bo->base.io);
4835
			assert(bo->base.io);
4836
			assert(bo->base.refcnt >= 1);
4836
			assert(bo->base.refcnt >= 1);
4837
			assert(bo->mmapped);
4837
			assert(bo->mmapped);
4838
			assert(!IS_CPU_MAP(bo->base.map) || kgem->has_llc || bo->base.snoop);
4838
			assert(!IS_CPU_MAP(bo->base.map) || kgem->has_llc || bo->base.snoop);
4839
 
4839
 
4840
			if (!kgem->has_llc && (bo->write & ~flags) & KGEM_BUFFER_INPLACE) {
4840
			if (!kgem->has_llc && (bo->write & ~flags) & KGEM_BUFFER_INPLACE) {
4841
				DBG(("%s: skip write %x buffer, need %x\n",
4841
				DBG(("%s: skip write %x buffer, need %x\n",
4842
				     __FUNCTION__, bo->write, flags));
4842
				     __FUNCTION__, bo->write, flags));
4843
				continue;
4843
				continue;
4844
			}
4844
			}
4845
 
4845
 
4846
			if (bo->used + size <= bytes(&bo->base)) {
4846
			if (bo->used + size <= bytes(&bo->base)) {
4847
				DBG(("%s: reusing buffer? used=%d + size=%d, total=%d\n",
4847
				DBG(("%s: reusing buffer? used=%d + size=%d, total=%d\n",
4848
				     __FUNCTION__, bo->used, size, bytes(&bo->base)));
4848
				     __FUNCTION__, bo->used, size, bytes(&bo->base)));
4849
				offset = bo->used;
4849
				offset = bo->used;
4850
				bo->used += size;
4850
				bo->used += size;
4851
				list_move(&bo->base.list, &kgem->batch_buffers);
4851
				list_move(&bo->base.list, &kgem->batch_buffers);
4852
				goto done;
4852
				goto done;
4853
			}
4853
			}
4854
		}
4854
		}
4855
	}
4855
	}
4856
#endif
4856
#endif
4857
 
4857
 
4858
#if !DBG_NO_MAP_UPLOAD
4858
#if !DBG_NO_MAP_UPLOAD
4859
	/* Be a little more generous and hope to hold fewer mmappings */
4859
	/* Be a little more generous and hope to hold fewer mmappings */
4860
	alloc = ALIGN(2*size, kgem->buffer_size);
4860
	alloc = ALIGN(2*size, kgem->buffer_size);
4861
	if (alloc > MAX_CACHE_SIZE)
4861
	if (alloc > MAX_CACHE_SIZE)
4862
		alloc = ALIGN(size, kgem->buffer_size);
4862
		alloc = ALIGN(size, kgem->buffer_size);
4863
	if (alloc > MAX_CACHE_SIZE)
4863
	if (alloc > MAX_CACHE_SIZE)
4864
		alloc = PAGE_ALIGN(size);
4864
		alloc = PAGE_ALIGN(size);
4865
	assert(alloc);
4865
	assert(alloc);
4866
 
4866
 
4867
	if (alloc > kgem->aperture_mappable / 4)
4867
	if (alloc > kgem->aperture_mappable / 4)
4868
		flags &= ~KGEM_BUFFER_INPLACE;
4868
		flags &= ~KGEM_BUFFER_INPLACE;
4869
	alloc /= PAGE_SIZE;
4869
	alloc /= PAGE_SIZE;
4870
 
4870
 
4871
	if (kgem->has_llc &&
4871
	if (kgem->has_llc &&
4872
	    (flags & KGEM_BUFFER_WRITE_INPLACE) != KGEM_BUFFER_WRITE_INPLACE) {
4872
	    (flags & KGEM_BUFFER_WRITE_INPLACE) != KGEM_BUFFER_WRITE_INPLACE) {
4873
		bo = buffer_alloc();
4873
		bo = buffer_alloc();
4874
		if (bo == NULL)
4874
		if (bo == NULL)
4875
			goto skip_llc;
4875
			goto skip_llc;
4876
 
4876
 
4877
		old = NULL;
4877
		old = NULL;
4878
		if ((flags & KGEM_BUFFER_WRITE) == 0)
4878
		if ((flags & KGEM_BUFFER_WRITE) == 0)
4879
			old = search_linear_cache(kgem, alloc, CREATE_CPU_MAP);
4879
			old = search_linear_cache(kgem, alloc, CREATE_CPU_MAP);
4880
		if (old == NULL)
4880
		if (old == NULL)
4881
			old = search_linear_cache(kgem, alloc, CREATE_INACTIVE | CREATE_CPU_MAP);
4881
			old = search_linear_cache(kgem, alloc, CREATE_INACTIVE | CREATE_CPU_MAP);
4882
		if (old == NULL)
4882
		if (old == NULL)
4883
			old = search_linear_cache(kgem, NUM_PAGES(size), CREATE_INACTIVE | CREATE_CPU_MAP);
4883
			old = search_linear_cache(kgem, NUM_PAGES(size), CREATE_INACTIVE | CREATE_CPU_MAP);
4884
		if (old) {
4884
		if (old) {
4885
			DBG(("%s: found LLC handle=%d for buffer\n",
4885
			DBG(("%s: found LLC handle=%d for buffer\n",
4886
			     __FUNCTION__, old->handle));
4886
			     __FUNCTION__, old->handle));
4887
 
4887
 
4888
			init_buffer_from_bo(bo, old);
4888
			init_buffer_from_bo(bo, old);
4889
		} else {
4889
		} else {
4890
			uint32_t handle = gem_create(kgem->fd, alloc);
4890
			uint32_t handle = gem_create(kgem->fd, alloc);
4891
			if (handle == 0) {
4891
			if (handle == 0) {
4892
				free(bo);
4892
				free(bo);
4893
				goto skip_llc;
4893
				goto skip_llc;
4894
			}
4894
			}
4895
			__kgem_bo_init(&bo->base, handle, alloc);
4895
			__kgem_bo_init(&bo->base, handle, alloc);
4896
			DBG(("%s: created LLC handle=%d for buffer\n",
4896
			DBG(("%s: created LLC handle=%d for buffer\n",
4897
			     __FUNCTION__, bo->base.handle));
4897
			     __FUNCTION__, bo->base.handle));
4898
 
4898
 
4899
			debug_alloc(kgem, alloc);
4899
			debug_alloc(kgem, alloc);
4900
		}
4900
		}
4901
 
4901
 
4902
		assert(bo->mmapped);
4902
		assert(bo->mmapped);
4903
		assert(!bo->need_io);
4903
		assert(!bo->need_io);
4904
 
4904
 
4905
		bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
4905
		bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
4906
		if (bo->mem) {
4906
		if (bo->mem) {
4907
			if (flags & KGEM_BUFFER_WRITE)
4907
			if (flags & KGEM_BUFFER_WRITE)
4908
				kgem_bo_sync__cpu(kgem, &bo->base);
4908
				kgem_bo_sync__cpu(kgem, &bo->base);
4909
			flags &= ~KGEM_BUFFER_INPLACE;
4909
			flags &= ~KGEM_BUFFER_INPLACE;
4910
			goto init;
4910
			goto init;
4911
		} else {
4911
		} else {
4912
			bo->base.refcnt = 0; /* for valgrind */
4912
			bo->base.refcnt = 0; /* for valgrind */
4913
			kgem_bo_free(kgem, &bo->base);
4913
			kgem_bo_free(kgem, &bo->base);
4914
		}
4914
		}
4915
	}
4915
	}
4916
skip_llc:
4916
skip_llc:
4917
 
4917
 
4918
	if ((flags & KGEM_BUFFER_WRITE_INPLACE) == KGEM_BUFFER_WRITE_INPLACE) {
4918
	if ((flags & KGEM_BUFFER_WRITE_INPLACE) == KGEM_BUFFER_WRITE_INPLACE) {
4919
		/* The issue with using a GTT upload buffer is that we may
4919
		/* The issue with using a GTT upload buffer is that we may
4920
		 * cause eviction-stalls in order to free up some GTT space.
4920
		 * cause eviction-stalls in order to free up some GTT space.
4921
		 * An is-mappable? ioctl could help us detect when we are
4921
		 * An is-mappable? ioctl could help us detect when we are
4922
		 * about to block, or some per-page magic in the kernel.
4922
		 * about to block, or some per-page magic in the kernel.
4923
		 *
4923
		 *
4924
		 * XXX This is especially noticeable on memory constrained
4924
		 * XXX This is especially noticeable on memory constrained
4925
		 * devices like gen2 or with relatively slow gpu like i3.
4925
		 * devices like gen2 or with relatively slow gpu like i3.
4926
		 */
4926
		 */
4927
		DBG(("%s: searching for an inactive GTT map for upload\n",
4927
		DBG(("%s: searching for an inactive GTT map for upload\n",
4928
		     __FUNCTION__));
4928
		     __FUNCTION__));
4929
		old = search_linear_cache(kgem, alloc,
4929
		old = search_linear_cache(kgem, alloc,
4930
					  CREATE_EXACT | CREATE_INACTIVE | CREATE_GTT_MAP);
4930
					  CREATE_EXACT | CREATE_INACTIVE | CREATE_GTT_MAP);
4931
#if HAVE_I915_GEM_BUFFER_INFO
4931
#if HAVE_I915_GEM_BUFFER_INFO
4932
		if (old) {
4932
		if (old) {
4933
			struct drm_i915_gem_buffer_info info;
4933
			struct drm_i915_gem_buffer_info info;
4934
 
4934
 
4935
			/* An example of such a non-blocking ioctl might work */
4935
			/* An example of such a non-blocking ioctl might work */
4936
 
4936
 
4937
			VG_CLEAR(info);
4937
			VG_CLEAR(info);
4938
			info.handle = handle;
4938
			info.handle = handle;
4939
			if (drmIoctl(kgem->fd,
4939
			if (drmIoctl(kgem->fd,
4940
				     DRM_IOCTL_I915_GEM_BUFFER_INFO,
4940
				     DRM_IOCTL_I915_GEM_BUFFER_INFO,
4941
				     &fino) == 0) {
4941
				     &fino) == 0) {
4942
				old->presumed_offset = info.addr;
4942
				old->presumed_offset = info.addr;
4943
				if ((info.flags & I915_GEM_MAPPABLE) == 0) {
4943
				if ((info.flags & I915_GEM_MAPPABLE) == 0) {
4944
					kgem_bo_move_to_inactive(kgem, old);
4944
					kgem_bo_move_to_inactive(kgem, old);
4945
					old = NULL;
4945
					old = NULL;
4946
				}
4946
				}
4947
			}
4947
			}
4948
		}
4948
		}
4949
#endif
4949
#endif
4950
		if (old == NULL)
4950
		if (old == NULL)
4951
			old = search_linear_cache(kgem, NUM_PAGES(size),
4951
			old = search_linear_cache(kgem, NUM_PAGES(size),
4952
						  CREATE_EXACT | CREATE_INACTIVE | CREATE_GTT_MAP);
4952
						  CREATE_EXACT | CREATE_INACTIVE | CREATE_GTT_MAP);
4953
		if (old == NULL) {
4953
		if (old == NULL) {
4954
			old = search_linear_cache(kgem, alloc, CREATE_INACTIVE);
4954
			old = search_linear_cache(kgem, alloc, CREATE_INACTIVE);
4955
			if (old && !__kgem_bo_is_mappable(kgem, old)) {
4955
			if (old && !__kgem_bo_is_mappable(kgem, old)) {
4956
				_kgem_bo_destroy(kgem, old);
4956
				_kgem_bo_destroy(kgem, old);
4957
				old = NULL;
4957
				old = NULL;
4958
			}
4958
			}
4959
		}
4959
		}
4960
		if (old) {
4960
		if (old) {
4961
			DBG(("%s: reusing handle=%d for buffer\n",
4961
			DBG(("%s: reusing handle=%d for buffer\n",
4962
			     __FUNCTION__, old->handle));
4962
			     __FUNCTION__, old->handle));
4963
			assert(__kgem_bo_is_mappable(kgem, old));
4963
			assert(__kgem_bo_is_mappable(kgem, old));
4964
			assert(!old->snoop);
4964
			assert(!old->snoop);
4965
			assert(old->rq == NULL);
4965
			assert(old->rq == NULL);
4966
 
4966
 
4967
			bo = buffer_alloc();
4967
			bo = buffer_alloc();
4968
			if (bo == NULL)
4968
			if (bo == NULL)
4969
				return NULL;
4969
				return NULL;
4970
 
4970
 
4971
			init_buffer_from_bo(bo, old);
4971
			init_buffer_from_bo(bo, old);
4972
			assert(num_pages(&bo->base) >= NUM_PAGES(size));
4972
			assert(num_pages(&bo->base) >= NUM_PAGES(size));
4973
 
4973
 
4974
			assert(bo->mmapped);
4974
			assert(bo->mmapped);
4975
			assert(bo->base.refcnt == 1);
4975
			assert(bo->base.refcnt == 1);
4976
 
4976
 
4977
			bo->mem = kgem_bo_map(kgem, &bo->base);
4977
			bo->mem = kgem_bo_map(kgem, &bo->base);
4978
			if (bo->mem) {
4978
			if (bo->mem) {
4979
				if (IS_CPU_MAP(bo->base.map))
4979
				if (IS_CPU_MAP(bo->base.map))
4980
					flags &= ~KGEM_BUFFER_INPLACE;
4980
					flags &= ~KGEM_BUFFER_INPLACE;
4981
				goto init;
4981
				goto init;
4982
			} else {
4982
			} else {
4983
				bo->base.refcnt = 0;
4983
				bo->base.refcnt = 0;
4984
				kgem_bo_free(kgem, &bo->base);
4984
				kgem_bo_free(kgem, &bo->base);
4985
			}
4985
			}
4986
		}
4986
		}
4987
	}
4987
	}
4988
#else
4988
#else
4989
	flags &= ~KGEM_BUFFER_INPLACE;
4989
	flags &= ~KGEM_BUFFER_INPLACE;
4990
#endif
4990
#endif
4991
	/* Be more parsimonious with pwrite/pread/cacheable buffers */
4991
	/* Be more parsimonious with pwrite/pread/cacheable buffers */
4992
	if ((flags & KGEM_BUFFER_INPLACE) == 0)
4992
	if ((flags & KGEM_BUFFER_INPLACE) == 0)
4993
		alloc = NUM_PAGES(size);
4993
		alloc = NUM_PAGES(size);
4994
 
4994
 
4995
	if (use_snoopable_buffer(kgem, flags)) {
4995
	if (use_snoopable_buffer(kgem, flags)) {
4996
		bo = search_snoopable_buffer(kgem, alloc);
4996
		bo = search_snoopable_buffer(kgem, alloc);
4997
		if (bo) {
4997
		if (bo) {
4998
			if (flags & KGEM_BUFFER_WRITE)
4998
			if (flags & KGEM_BUFFER_WRITE)
4999
				kgem_bo_sync__cpu(kgem, &bo->base);
4999
				kgem_bo_sync__cpu(kgem, &bo->base);
5000
			flags &= ~KGEM_BUFFER_INPLACE;
5000
			flags &= ~KGEM_BUFFER_INPLACE;
5001
			goto init;
5001
			goto init;
5002
		}
5002
		}
5003
 
5003
 
5004
		if ((flags & KGEM_BUFFER_INPLACE) == 0) {
5004
		if ((flags & KGEM_BUFFER_INPLACE) == 0) {
5005
			bo = create_snoopable_buffer(kgem, alloc);
5005
			bo = create_snoopable_buffer(kgem, alloc);
5006
			if (bo)
5006
			if (bo)
5007
				goto init;
5007
				goto init;
5008
		}
5008
		}
5009
	}
5009
	}
5010
 
5010
 
5011
	flags &= ~KGEM_BUFFER_INPLACE;
5011
	flags &= ~KGEM_BUFFER_INPLACE;
5012
 
5012
 
5013
	old = NULL;
5013
	old = NULL;
5014
	if ((flags & KGEM_BUFFER_WRITE) == 0)
5014
	if ((flags & KGEM_BUFFER_WRITE) == 0)
5015
		old = search_linear_cache(kgem, alloc, 0);
5015
		old = search_linear_cache(kgem, alloc, 0);
5016
	if (old == NULL)
5016
	if (old == NULL)
5017
		old = search_linear_cache(kgem, alloc, CREATE_INACTIVE);
5017
		old = search_linear_cache(kgem, alloc, CREATE_INACTIVE);
5018
	if (old) {
5018
	if (old) {
5019
		DBG(("%s: reusing ordinary handle %d for io\n",
5019
		DBG(("%s: reusing ordinary handle %d for io\n",
5020
		     __FUNCTION__, old->handle));
5020
		     __FUNCTION__, old->handle));
5021
		bo = buffer_alloc_with_data(num_pages(old));
5021
		bo = buffer_alloc_with_data(num_pages(old));
5022
		if (bo == NULL)
5022
		if (bo == NULL)
5023
			return NULL;
5023
			return NULL;
5024
 
5024
 
5025
		init_buffer_from_bo(bo, old);
5025
		init_buffer_from_bo(bo, old);
5026
		bo->need_io = flags & KGEM_BUFFER_WRITE;
5026
		bo->need_io = flags & KGEM_BUFFER_WRITE;
5027
	} else {
5027
	} else {
5028
		unsigned hint;
5028
		unsigned hint;
5029
 
5029
 
5030
		if (use_snoopable_buffer(kgem, flags)) {
5030
		if (use_snoopable_buffer(kgem, flags)) {
5031
			bo = create_snoopable_buffer(kgem, alloc);
5031
			bo = create_snoopable_buffer(kgem, alloc);
5032
			if (bo)
5032
			if (bo)
5033
				goto init;
5033
				goto init;
5034
		}
5034
		}
5035
 
5035
 
5036
		bo = buffer_alloc();
5036
		bo = buffer_alloc();
5037
		if (bo == NULL)
5037
		if (bo == NULL)
5038
			return NULL;
5038
			return NULL;
5039
 
5039
 
5040
		hint = CREATE_INACTIVE;
5040
		hint = CREATE_INACTIVE;
5041
		if (flags & KGEM_BUFFER_WRITE)
5041
		if (flags & KGEM_BUFFER_WRITE)
5042
			hint |= CREATE_CPU_MAP;
5042
			hint |= CREATE_CPU_MAP;
5043
		old = search_linear_cache(kgem, alloc, hint);
5043
		old = search_linear_cache(kgem, alloc, hint);
5044
		if (old) {
5044
		if (old) {
5045
			DBG(("%s: reusing handle=%d for buffer\n",
5045
			DBG(("%s: reusing handle=%d for buffer\n",
5046
			     __FUNCTION__, old->handle));
5046
			     __FUNCTION__, old->handle));
5047
 
5047
 
5048
			init_buffer_from_bo(bo, old);
5048
			init_buffer_from_bo(bo, old);
5049
		} else {
5049
		} else {
5050
			uint32_t handle = gem_create(kgem->fd, alloc);
5050
			uint32_t handle = gem_create(kgem->fd, alloc);
5051
			if (handle == 0) {
5051
			if (handle == 0) {
5052
				free(bo);
5052
				free(bo);
5053
				return NULL;
5053
				return NULL;
5054
			}
5054
			}
5055
 
5055
 
5056
			DBG(("%s: created handle=%d for buffer\n",
5056
			DBG(("%s: created handle=%d for buffer\n",
5057
			     __FUNCTION__, handle));
5057
			     __FUNCTION__, handle));
5058
 
5058
 
5059
			__kgem_bo_init(&bo->base, handle, alloc);
5059
			__kgem_bo_init(&bo->base, handle, alloc);
5060
			debug_alloc(kgem, alloc * PAGE_SIZE);
5060
			debug_alloc(kgem, alloc * PAGE_SIZE);
5061
		}
5061
		}
5062
 
5062
 
5063
		assert(bo->mmapped);
5063
		assert(bo->mmapped);
5064
		assert(!bo->need_io);
5064
		assert(!bo->need_io);
5065
		assert(bo->base.refcnt == 1);
5065
		assert(bo->base.refcnt == 1);
5066
 
5066
 
5067
		if (flags & KGEM_BUFFER_WRITE) {
5067
		if (flags & KGEM_BUFFER_WRITE) {
5068
			bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
5068
			bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
5069
			if (bo->mem != NULL) {
5069
			if (bo->mem != NULL) {
5070
				kgem_bo_sync__cpu(kgem, &bo->base);
5070
				kgem_bo_sync__cpu(kgem, &bo->base);
5071
				goto init;
5071
				goto init;
5072
			}
5072
			}
5073
		}
5073
		}
5074
 
5074
 
5075
		DBG(("%s: failing back to new pwrite buffer\n", __FUNCTION__));
5075
		DBG(("%s: failing back to new pwrite buffer\n", __FUNCTION__));
5076
		old = &bo->base;
5076
		old = &bo->base;
5077
		bo = buffer_alloc_with_data(num_pages(old));
5077
		bo = buffer_alloc_with_data(num_pages(old));
5078
		if (bo == NULL) {
5078
		if (bo == NULL) {
5079
			old->refcnt= 0;
5079
			old->refcnt= 0;
5080
			kgem_bo_free(kgem, old);
5080
			kgem_bo_free(kgem, old);
5081
			return NULL;
5081
			return NULL;
5082
		}
5082
		}
5083
 
5083
 
5084
		init_buffer_from_bo(bo, old);
5084
		init_buffer_from_bo(bo, old);
5085
 
5085
 
5086
		assert(bo->mem);
5086
		assert(bo->mem);
5087
		assert(!bo->mmapped);
5087
		assert(!bo->mmapped);
5088
		assert(bo->base.refcnt == 1);
5088
		assert(bo->base.refcnt == 1);
5089
 
5089
 
5090
		bo->need_io = flags & KGEM_BUFFER_WRITE;
5090
		bo->need_io = flags & KGEM_BUFFER_WRITE;
5091
	}
5091
	}
5092
init:
5092
init:
5093
	bo->base.io = true;
5093
	bo->base.io = true;
5094
	assert(bo->base.refcnt == 1);
5094
	assert(bo->base.refcnt == 1);
5095
	assert(num_pages(&bo->base) >= NUM_PAGES(size));
5095
	assert(num_pages(&bo->base) >= NUM_PAGES(size));
5096
	assert(!bo->need_io || !bo->base.needs_flush);
5096
	assert(!bo->need_io || !bo->base.needs_flush);
5097
	assert(!bo->need_io || bo->base.domain != DOMAIN_GPU);
5097
	assert(!bo->need_io || bo->base.domain != DOMAIN_GPU);
5098
	assert(bo->mem);
5098
	assert(bo->mem);
5099
	assert(!bo->mmapped || bo->base.map != NULL);
5099
	assert(!bo->mmapped || bo->base.map != NULL);
5100
 
5100
 
5101
	bo->used = size;
5101
	bo->used = size;
5102
	bo->write = flags & KGEM_BUFFER_WRITE_INPLACE;
5102
	bo->write = flags & KGEM_BUFFER_WRITE_INPLACE;
5103
	offset = 0;
5103
	offset = 0;
5104
 
5104
 
5105
	assert(list_is_empty(&bo->base.list));
5105
	assert(list_is_empty(&bo->base.list));
5106
	list_add(&bo->base.list, &kgem->batch_buffers);
5106
	list_add(&bo->base.list, &kgem->batch_buffers);
5107
 
5107
 
5108
	DBG(("%s(pages=%d [%d]) new handle=%d, used=%d, write=%d\n",
5108
	DBG(("%s(pages=%d [%d]) new handle=%d, used=%d, write=%d\n",
5109
	     __FUNCTION__, num_pages(&bo->base), alloc, bo->base.handle, bo->used, bo->write));
5109
	     __FUNCTION__, num_pages(&bo->base), alloc, bo->base.handle, bo->used, bo->write));
5110
 
5110
 
5111
done:
5111
done:
5112
	bo->used = ALIGN(bo->used, UPLOAD_ALIGNMENT);
5112
	bo->used = ALIGN(bo->used, UPLOAD_ALIGNMENT);
5113
	assert(bo->mem);
5113
	assert(bo->mem);
5114
	*ret = (char *)bo->mem + offset;
5114
	*ret = (char *)bo->mem + offset;
5115
	return kgem_create_proxy(kgem, &bo->base, offset, size);
5115
	return kgem_create_proxy(kgem, &bo->base, offset, size);
5116
}
5116
}
5117
 
5117
 
5118
bool kgem_buffer_is_inplace(struct kgem_bo *_bo)
5118
bool kgem_buffer_is_inplace(struct kgem_bo *_bo)
5119
{
5119
{
5120
	struct kgem_buffer *bo = (struct kgem_buffer *)_bo->proxy;
5120
	struct kgem_buffer *bo = (struct kgem_buffer *)_bo->proxy;
5121
	return bo->write & KGEM_BUFFER_WRITE_INPLACE;
5121
	return bo->write & KGEM_BUFFER_WRITE_INPLACE;
5122
}
5122
}
5123
 
5123
 
5124
struct kgem_bo *kgem_create_buffer_2d(struct kgem *kgem,
5124
struct kgem_bo *kgem_create_buffer_2d(struct kgem *kgem,
5125
				      int width, int height, int bpp,
5125
				      int width, int height, int bpp,
5126
				      uint32_t flags,
5126
				      uint32_t flags,
5127
				      void **ret)
5127
				      void **ret)
5128
{
5128
{
5129
	struct kgem_bo *bo;
5129
	struct kgem_bo *bo;
5130
	int stride;
5130
	int stride;
5131
 
5131
 
5132
	assert(width > 0 && height > 0);
5132
	assert(width > 0 && height > 0);
5133
	assert(ret != NULL);
5133
	assert(ret != NULL);
5134
	stride = ALIGN(width, 2) * bpp >> 3;
5134
	stride = ALIGN(width, 2) * bpp >> 3;
5135
	stride = ALIGN(stride, 4);
5135
	stride = ALIGN(stride, 4);
5136
 
5136
 
5137
	DBG(("%s: %dx%d, %d bpp, stride=%d\n",
5137
	DBG(("%s: %dx%d, %d bpp, stride=%d\n",
5138
	     __FUNCTION__, width, height, bpp, stride));
5138
	     __FUNCTION__, width, height, bpp, stride));
5139
 
5139
 
5140
	bo = kgem_create_buffer(kgem, stride * ALIGN(height, 2), flags, ret);
5140
	bo = kgem_create_buffer(kgem, stride * ALIGN(height, 2), flags, ret);
5141
	if (bo == NULL) {
5141
	if (bo == NULL) {
5142
		DBG(("%s: allocation failure for upload buffer\n",
5142
		DBG(("%s: allocation failure for upload buffer\n",
5143
		     __FUNCTION__));
5143
		     __FUNCTION__));
5144
		return NULL;
5144
		return NULL;
5145
	}
5145
	}
5146
	assert(*ret != NULL);
5146
	assert(*ret != NULL);
5147
	assert(bo->proxy != NULL);
5147
	assert(bo->proxy != NULL);
5148
 
5148
 
5149
	if (height & 1) {
5149
	if (height & 1) {
5150
		struct kgem_buffer *io = (struct kgem_buffer *)bo->proxy;
5150
		struct kgem_buffer *io = (struct kgem_buffer *)bo->proxy;
5151
		int min;
5151
		int min;
5152
 
5152
 
5153
		assert(io->used);
5153
		assert(io->used);
5154
 
5154
 
5155
		/* Having padded this surface to ensure that accesses to
5155
		/* Having padded this surface to ensure that accesses to
5156
		 * the last pair of rows is valid, remove the padding so
5156
		 * the last pair of rows is valid, remove the padding so
5157
		 * that it can be allocated to other pixmaps.
5157
		 * that it can be allocated to other pixmaps.
5158
		 */
5158
		 */
5159
		min = bo->delta + height * stride;
5159
		min = bo->delta + height * stride;
5160
		min = ALIGN(min, UPLOAD_ALIGNMENT);
5160
		min = ALIGN(min, UPLOAD_ALIGNMENT);
5161
		if (io->used != min) {
5161
		if (io->used != min) {
5162
			DBG(("%s: trimming buffer from %d to %d\n",
5162
			DBG(("%s: trimming buffer from %d to %d\n",
5163
			     __FUNCTION__, io->used, min));
5163
			     __FUNCTION__, io->used, min));
5164
			io->used = min;
5164
			io->used = min;
5165
		}
5165
		}
5166
		bo->size.bytes -= stride;
5166
		bo->size.bytes -= stride;
5167
	}
5167
	}
5168
 
5168
 
5169
	bo->map = MAKE_CPU_MAP(*ret);
5169
	bo->map = MAKE_CPU_MAP(*ret);
5170
	bo->pitch = stride;
5170
	bo->pitch = stride;
5171
	bo->unique_id = kgem_get_unique_id(kgem);
5171
	bo->unique_id = kgem_get_unique_id(kgem);
5172
	return bo;
5172
	return bo;
5173
}
5173
}
5174
 
5174
 
5175
struct kgem_bo *kgem_upload_source_image(struct kgem *kgem,
5175
struct kgem_bo *kgem_upload_source_image(struct kgem *kgem,
5176
					 const void *data,
5176
					 const void *data,
5177
					 const BoxRec *box,
5177
					 const BoxRec *box,
5178
					 int stride, int bpp)
5178
					 int stride, int bpp)
5179
{
5179
{
5180
	int width  = box->x2 - box->x1;
5180
	int width  = box->x2 - box->x1;
5181
	int height = box->y2 - box->y1;
5181
	int height = box->y2 - box->y1;
5182
	struct kgem_bo *bo;
5182
	struct kgem_bo *bo;
5183
	void *dst;
5183
	void *dst;
5184
 
5184
 
5185
	if (!kgem_can_create_2d(kgem, width, height, bpp))
5185
	if (!kgem_can_create_2d(kgem, width, height, bpp))
5186
		return NULL;
5186
		return NULL;
5187
 
5187
 
5188
	DBG(("%s : (%d, %d), (%d, %d), stride=%d, bpp=%d\n",
5188
	DBG(("%s : (%d, %d), (%d, %d), stride=%d, bpp=%d\n",
5189
	     __FUNCTION__, box->x1, box->y1, box->x2, box->y2, stride, bpp));
5189
	     __FUNCTION__, box->x1, box->y1, box->x2, box->y2, stride, bpp));
5190
 
5190
 
5191
	assert(data);
5191
	assert(data);
5192
	assert(width > 0);
5192
	assert(width > 0);
5193
	assert(height > 0);
5193
	assert(height > 0);
5194
	assert(stride);
5194
	assert(stride);
5195
	assert(bpp);
5195
	assert(bpp);
5196
 
5196
 
5197
	bo = kgem_create_buffer_2d(kgem,
5197
	bo = kgem_create_buffer_2d(kgem,
5198
				   width, height, bpp,
5198
				   width, height, bpp,
5199
				   KGEM_BUFFER_WRITE_INPLACE, &dst);
5199
				   KGEM_BUFFER_WRITE_INPLACE, &dst);
5200
	if (bo)
5200
	if (bo)
5201
		memcpy_blt(data, dst, bpp,
5201
		memcpy_blt(data, dst, bpp,
5202
			   stride, bo->pitch,
5202
			   stride, bo->pitch,
5203
			   box->x1, box->y1,
5203
			   box->x1, box->y1,
5204
			   0, 0,
5204
			   0, 0,
5205
			   width, height);
5205
			   width, height);
5206
 
5206
 
5207
	return bo;
5207
	return bo;
5208
}
5208
}
5209
 
5209
 
5210
void kgem_proxy_bo_attach(struct kgem_bo *bo,
5210
void kgem_proxy_bo_attach(struct kgem_bo *bo,
5211
			  struct kgem_bo **ptr)
5211
			  struct kgem_bo **ptr)
5212
{
5212
{
5213
	DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
5213
	DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
5214
	assert(bo->map == NULL || IS_CPU_MAP(bo->map));
5214
	assert(bo->map == NULL || IS_CPU_MAP(bo->map));
5215
	assert(bo->proxy);
5215
	assert(bo->proxy);
5216
	list_add(&bo->vma, &bo->proxy->vma);
5216
	list_add(&bo->vma, &bo->proxy->vma);
5217
	bo->map = ptr;
5217
	bo->map = ptr;
5218
	*ptr = kgem_bo_reference(bo);
5218
	*ptr = kgem_bo_reference(bo);
5219
}
5219
}
5220
 
5220
 
5221
void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *_bo)
5221
void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *_bo)
5222
{
5222
{
5223
	struct kgem_buffer *bo;
5223
	struct kgem_buffer *bo;
5224
	uint32_t offset = _bo->delta, length = _bo->size.bytes;
5224
	uint32_t offset = _bo->delta, length = _bo->size.bytes;
5225
 
5225
 
5226
	/* We expect the caller to have already submitted the batch */
5226
	/* We expect the caller to have already submitted the batch */
5227
	assert(_bo->io);
5227
	assert(_bo->io);
5228
	assert(_bo->exec == NULL);
5228
	assert(_bo->exec == NULL);
5229
	assert(_bo->rq == NULL);
5229
	assert(_bo->rq == NULL);
5230
	assert(_bo->proxy);
5230
	assert(_bo->proxy);
5231
 
5231
 
5232
	_bo = _bo->proxy;
5232
	_bo = _bo->proxy;
5233
	assert(_bo->proxy == NULL);
5233
	assert(_bo->proxy == NULL);
5234
	assert(_bo->exec == NULL);
5234
	assert(_bo->exec == NULL);
5235
 
5235
 
5236
	bo = (struct kgem_buffer *)_bo;
5236
	bo = (struct kgem_buffer *)_bo;
5237
 
5237
 
5238
	DBG(("%s(offset=%d, length=%d, snooped=%d)\n", __FUNCTION__,
5238
	DBG(("%s(offset=%d, length=%d, snooped=%d)\n", __FUNCTION__,
5239
	     offset, length, bo->base.snoop));
5239
	     offset, length, bo->base.snoop));
5240
 
5240
 
5241
	if (bo->mmapped) {
5241
	if (bo->mmapped) {
5242
		struct drm_i915_gem_set_domain set_domain;
5242
		struct drm_i915_gem_set_domain set_domain;
5243
 
5243
 
5244
		DBG(("%s: sync: needs_flush? %d, domain? %d, busy? %d\n",
5244
		DBG(("%s: sync: needs_flush? %d, domain? %d, busy? %d\n",
5245
		     __FUNCTION__,
5245
		     __FUNCTION__,
5246
		     bo->base.needs_flush,
5246
		     bo->base.needs_flush,
5247
		     bo->base.domain,
5247
		     bo->base.domain,
5248
		     __kgem_busy(kgem, bo->base.handle)));
5248
		     __kgem_busy(kgem, bo->base.handle)));
5249
 
5249
 
5250
		assert(!IS_CPU_MAP(bo->base.map) || bo->base.snoop || kgem->has_llc);
5250
		assert(!IS_CPU_MAP(bo->base.map) || bo->base.snoop || kgem->has_llc);
5251
 
5251
 
5252
		VG_CLEAR(set_domain);
5252
		VG_CLEAR(set_domain);
5253
		set_domain.handle = bo->base.handle;
5253
		set_domain.handle = bo->base.handle;
5254
		set_domain.write_domain = 0;
5254
		set_domain.write_domain = 0;
5255
		set_domain.read_domains =
5255
		set_domain.read_domains =
5256
			IS_CPU_MAP(bo->base.map) ? I915_GEM_DOMAIN_CPU : I915_GEM_DOMAIN_GTT;
5256
			IS_CPU_MAP(bo->base.map) ? I915_GEM_DOMAIN_CPU : I915_GEM_DOMAIN_GTT;
5257
 
5257
 
5258
		if (drmIoctl(kgem->fd,
5258
		if (drmIoctl(kgem->fd,
5259
			     DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain))
5259
			     DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain))
5260
			return;
5260
			return;
5261
	} else {
5261
	} else {
5262
		if (gem_read(kgem->fd,
5262
		if (gem_read(kgem->fd,
5263
			     bo->base.handle, (char *)bo->mem+offset,
5263
			     bo->base.handle, (char *)bo->mem+offset,
5264
			     offset, length))
5264
			     offset, length))
5265
			return;
5265
			return;
5266
	}
5266
	}
5267
	kgem_bo_retire(kgem, &bo->base);
5267
	kgem_bo_retire(kgem, &bo->base);
5268
	bo->base.domain = DOMAIN_NONE;
5268
	bo->base.domain = DOMAIN_NONE;
5269
}
5269
}
5270
#endif
5270
#endif
5271
 
5271
 
5272
uint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format)
5272
uint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format)
5273
{
5273
{
5274
	struct kgem_bo_binding *b;
5274
	struct kgem_bo_binding *b;
5275
 
5275
 
5276
	for (b = &bo->binding; b && b->offset; b = b->next)
5276
	for (b = &bo->binding; b && b->offset; b = b->next)
5277
		if (format == b->format)
5277
		if (format == b->format)
5278
			return b->offset;
5278
			return b->offset;
5279
 
5279
 
5280
	return 0;
5280
	return 0;
5281
}
5281
}
5282
 
5282
 
5283
void kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset)
5283
void kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset)
5284
{
5284
{
5285
	struct kgem_bo_binding *b;
5285
	struct kgem_bo_binding *b;
5286
 
5286
 
5287
	for (b = &bo->binding; b; b = b->next) {
5287
	for (b = &bo->binding; b; b = b->next) {
5288
		if (b->offset)
5288
		if (b->offset)
5289
			continue;
5289
			continue;
5290
 
5290
 
5291
		b->offset = offset;
5291
		b->offset = offset;
5292
		b->format = format;
5292
		b->format = format;
5293
 
5293
 
5294
		if (b->next)
5294
		if (b->next)
5295
			b->next->offset = 0;
5295
			b->next->offset = 0;
5296
 
5296
 
5297
		return;
5297
		return;
5298
	}
5298
	}
5299
 
5299
 
5300
	b = malloc(sizeof(*b));
5300
	b = malloc(sizeof(*b));
5301
	if (b) {
5301
	if (b) {
5302
		b->next = bo->binding.next;
5302
		b->next = bo->binding.next;
5303
		b->format = format;
5303
		b->format = format;
5304
		b->offset = offset;
5304
		b->offset = offset;
5305
		bo->binding.next = b;
5305
		bo->binding.next = b;
5306
	}
5306
	}
5307
}
5307
}
5308
 
5308
 
5309
int kgem_init_fb(struct kgem *kgem, struct sna_fb *fb)
5309
int kgem_init_fb(struct kgem *kgem, struct sna_fb *fb)
5310
{
5310
{
5311
    struct kgem_bo *bo;
5311
    struct kgem_bo *bo;
5312
    size_t size;
5312
    size_t size;
5313
    int ret;
5313
    int ret;
5314
 
5314
 
5315
	ret = drmIoctl(kgem->fd, SRV_FBINFO, fb);
5315
	ret = drmIoctl(kgem->fd, SRV_FBINFO, fb);
5316
	if( ret != 0 )
5316
	if( ret != 0 )
5317
	    return 0;
5317
	    return 0;
5318
 
5318
 
5319
    size = fb->pitch * fb->height / PAGE_SIZE;
5319
    size = fb->pitch * fb->height / PAGE_SIZE;
5320
 
5320
 
5321
  	bo = __kgem_bo_alloc(-2, size);
5321
  	bo = __kgem_bo_alloc(-2, size);
5322
	if (!bo) {
5322
	if (!bo) {
5323
		return 0;
5323
		return 0;
5324
	}
5324
	}
5325
 
5325
 
5326
	bo->domain    = DOMAIN_GTT;
5326
	bo->domain    = DOMAIN_GTT;
5327
	bo->unique_id = kgem_get_unique_id(kgem);
5327
	bo->unique_id = kgem_get_unique_id(kgem);
5328
	bo->pitch     = fb->pitch;
5328
	bo->pitch     = fb->pitch;
5329
    bo->tiling    = I915_TILING_NONE;
5329
    bo->tiling    = I915_TILING_X;
5330
    bo->scanout   = 1;
5330
    bo->scanout   = 1;
5331
	fb->fb_bo     = bo;
5331
	fb->fb_bo     = bo;
5332
 
5332
 
5333
//    printf("fb width %d height %d pitch %d bo %p\n",
5333
//    printf("fb width %d height %d pitch %d bo %p\n",
5334
//            fb->width, fb->height, fb->pitch, fb->fb_bo);
5334
//            fb->width, fb->height, fb->pitch, fb->fb_bo);
5335
 
5335
 
5336
    return 1;
5336
    return 1;
5337
};
5337
};
5338
 
5338
 
5339
 
5339
 
5340
int kgem_update_fb(struct kgem *kgem, struct sna_fb *fb)
5340
int kgem_update_fb(struct kgem *kgem, struct sna_fb *fb)
5341
{
5341
{
5342
    struct kgem_bo *bo;
5342
    struct kgem_bo *bo;
5343
    size_t size;
5343
    size_t size;
5344
    int ret;
5344
    int ret;
5345
 
5345
 
5346
    bo = fb->fb_bo;
5346
    bo = fb->fb_bo;
5347
 
5347
 
5348
	ret = drmIoctl(kgem->fd, SRV_FBINFO, fb);
5348
	ret = drmIoctl(kgem->fd, SRV_FBINFO, fb);
5349
	if( ret != 0 )
5349
	if( ret != 0 )
5350
	    return 0;
5350
	    return 0;
5351
 
5351
 
5352
	fb->fb_bo = bo;
5352
	fb->fb_bo = bo;
5353
 
5353
 
5354
    size = fb->pitch * fb->height / PAGE_SIZE;
5354
    size = fb->pitch * fb->height / PAGE_SIZE;
5355
 
5355
 
5356
    if((size != bo->size.pages.count) ||
5356
    if((size != bo->size.pages.count) ||
5357
       (fb->pitch != bo->pitch))
5357
       (fb->pitch != bo->pitch))
5358
    {
5358
    {
5359
        bo->size.pages.count = size;
5359
        bo->size.pages.count = size;
5360
	    bo->pitch     = fb->pitch;
5360
	    bo->pitch     = fb->pitch;
5361
 
5361
 
5362
    printf("fb width %d height %d pitch %d bo %p\n",
5362
    printf("fb width %d height %d pitch %d bo %p\n",
5363
            fb->width, fb->height, fb->pitch, fb->fb_bo);
5363
            fb->width, fb->height, fb->pitch, fb->fb_bo);
5364
 
5364
 
5365
        return 1;
5365
        return 1;
5366
    }
5366
    }
5367
 
5367
 
5368
    return 0;
5368
    return 0;
5369
};
5369
};
5370
 
5370
 
5371
void sna_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
5371
void sna_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
5372
{
5372
{
5373
    kgem_bo_destroy(kgem, bo);
5373
    kgem_bo_destroy(kgem, bo);
5374
    kgem_bo_free(kgem, bo);
5374
    kgem_bo_free(kgem, bo);
5375
}
5375
}
5376
 
5376
 
5377
 
5377
 
5378
void kgem_close_batches(struct kgem *kgem)
5378
void kgem_close_batches(struct kgem *kgem)
5379
{
5379
{
5380
    int n;
5380
    int n;
5381
 
5381
 
5382
	for (n = 0; n < ARRAY_SIZE(kgem->pinned_batches); n++) {
5382
	for (n = 0; n < ARRAY_SIZE(kgem->pinned_batches); n++) {
5383
		while (!list_is_empty(&kgem->pinned_batches[n])) {
5383
		while (!list_is_empty(&kgem->pinned_batches[n])) {
5384
			kgem_bo_destroy(kgem,
5384
			kgem_bo_destroy(kgem,
5385
					list_first_entry(&kgem->pinned_batches[n],
5385
					list_first_entry(&kgem->pinned_batches[n],
5386
							 struct kgem_bo, list));
5386
							 struct kgem_bo, list));
5387
		}
5387
		}
5388
	}
5388
	}
5389
};
5389
};
5390
 
5390
 
5391
struct kgem_bo *kgem_bo_from_handle(struct kgem *kgem, int handle,
5391
struct kgem_bo *kgem_bo_from_handle(struct kgem *kgem, int handle,
5392
                        int pitch, int height)
5392
                        int pitch, int height)
5393
{
5393
{
5394
	struct kgem_bo *bo;
5394
	struct kgem_bo *bo;
5395
    int size;
5395
    int size;
5396
 
5396
 
5397
    size = pitch * height / PAGE_SIZE;
5397
    size = pitch * height / PAGE_SIZE;
5398
 
5398
 
5399
  	bo = __kgem_bo_alloc(handle, size);
5399
  	bo = __kgem_bo_alloc(handle, size);
5400
    if(bo == NULL)
5400
    if(bo == NULL)
5401
        return NULL;
5401
        return NULL;
5402
 
5402
 
5403
	bo->domain    = DOMAIN_GTT;
5403
	bo->domain    = DOMAIN_GTT;
5404
	bo->unique_id = kgem_get_unique_id(kgem);
5404
	bo->unique_id = kgem_get_unique_id(kgem);
5405
	bo->pitch     = pitch;
5405
	bo->pitch     = pitch;
5406
    bo->tiling    = I915_TILING_X;
5406
    bo->tiling    = I915_TILING_X;
5407
    bo->scanout   = 0;
5407
    bo->scanout   = 0;
5408
 
5408
 
5409
    return bo;
5409
    return bo;
5410
}
5410
}
5411
>
5411
>
5412
>
5412
>
5413
#define>
5413
#define>
5414
#define>
5414
#define>
5415
struct>
5415
struct>
5416
struct>
5416
struct>
5417
#define>
5417
#define>
5418
#define>
5418
#define>
5419
#define>
5419
#define>
5420
#define>
5420
#define>