intel_bufmgr_gem.c revision fe517fc9
122944501Smrg/**************************************************************************
222944501Smrg *
322944501Smrg * Copyright � 2007 Red Hat Inc.
420131375Smrg * Copyright � 2007-2012 Intel Corporation
522944501Smrg * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
622944501Smrg * All Rights Reserved.
722944501Smrg *
822944501Smrg * Permission is hereby granted, free of charge, to any person obtaining a
922944501Smrg * copy of this software and associated documentation files (the
1022944501Smrg * "Software"), to deal in the Software without restriction, including
1122944501Smrg * without limitation the rights to use, copy, modify, merge, publish,
1222944501Smrg * distribute, sub license, and/or sell copies of the Software, and to
1322944501Smrg * permit persons to whom the Software is furnished to do so, subject to
1422944501Smrg * the following conditions:
1522944501Smrg *
1622944501Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1722944501Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1822944501Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
1922944501Smrg * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
2022944501Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2122944501Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2222944501Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE.
2322944501Smrg *
2422944501Smrg * The above copyright notice and this permission notice (including the
2522944501Smrg * next paragraph) shall be included in all copies or substantial portions
2622944501Smrg * of the Software.
2722944501Smrg *
2822944501Smrg *
2922944501Smrg **************************************************************************/
3022944501Smrg/*
3122944501Smrg * Authors: Thomas Hellstr�m <thomas-at-tungstengraphics-dot-com>
3222944501Smrg *          Keith Whitwell <keithw-at-tungstengraphics-dot-com>
3322944501Smrg *	    Eric Anholt <eric@anholt.net>
3422944501Smrg *	    Dave Airlie <airlied@linux.ie>
3522944501Smrg */
3622944501Smrg
3722944501Smrg#ifdef HAVE_CONFIG_H
3822944501Smrg#include "config.h"
3922944501Smrg#endif
4022944501Smrg
4122944501Smrg#include <xf86drm.h>
4222944501Smrg#include <xf86atomic.h>
4322944501Smrg#include <fcntl.h>
4422944501Smrg#include <stdio.h>
4522944501Smrg#include <stdlib.h>
4622944501Smrg#include <string.h>
4722944501Smrg#include <unistd.h>
4822944501Smrg#include <assert.h>
4922944501Smrg#include <pthread.h>
502e6867f6Smrg#include <stddef.h>
5122944501Smrg#include <sys/ioctl.h>
5222944501Smrg#include <sys/stat.h>
5322944501Smrg#include <sys/types.h>
5420131375Smrg#include <stdbool.h>
5522944501Smrg
5622944501Smrg#include "errno.h"
5720131375Smrg#ifndef ETIME
5820131375Smrg#define ETIME ETIMEDOUT
5920131375Smrg#endif
60424e9256Smrg#include "libdrm_macros.h"
6122944501Smrg#include "libdrm_lists.h"
6222944501Smrg#include "intel_bufmgr.h"
6322944501Smrg#include "intel_bufmgr_priv.h"
6422944501Smrg#include "intel_chipset.h"
6522944501Smrg#include "string.h"
6622944501Smrg
6722944501Smrg#include "i915_drm.h"
6822944501Smrg
6920131375Smrg#ifdef HAVE_VALGRIND
7020131375Smrg#include <valgrind.h>
7120131375Smrg#include <memcheck.h>
7220131375Smrg#define VG(x) x
7320131375Smrg#else
7420131375Smrg#define VG(x)
7520131375Smrg#endif
7620131375Smrg
77424e9256Smrg#define memclear(s) memset(&s, 0, sizeof(s))
7820131375Smrg
7922944501Smrg#define DBG(...) do {					\
8022944501Smrg	if (bufmgr_gem->bufmgr.debug)			\
8122944501Smrg		fprintf(stderr, __VA_ARGS__);		\
8222944501Smrg} while (0)
8322944501Smrg
84aaba2545Smrg#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
85fe517fc9Smrg#define MAX2(A, B) ((A) > (B) ? (A) : (B))
86fe517fc9Smrg
87fe517fc9Smrg/**
88fe517fc9Smrg * upper_32_bits - return bits 32-63 of a number
89fe517fc9Smrg * @n: the number we're accessing
90fe517fc9Smrg *
91fe517fc9Smrg * A basic shift-right of a 64- or 32-bit quantity.  Use this to suppress
92fe517fc9Smrg * the "right shift count >= width of type" warning when that quantity is
93fe517fc9Smrg * 32-bits.
94fe517fc9Smrg */
95fe517fc9Smrg#define upper_32_bits(n) ((__u32)(((n) >> 16) >> 16))
96fe517fc9Smrg
97fe517fc9Smrg/**
98fe517fc9Smrg * lower_32_bits - return bits 0-31 of a number
99fe517fc9Smrg * @n: the number we're accessing
100fe517fc9Smrg */
101fe517fc9Smrg#define lower_32_bits(n) ((__u32)(n))
102aaba2545Smrg
10322944501Smrgtypedef struct _drm_intel_bo_gem drm_intel_bo_gem;
10422944501Smrg
10522944501Smrgstruct drm_intel_gem_bo_bucket {
10622944501Smrg	drmMMListHead head;
10722944501Smrg	unsigned long size;
10822944501Smrg};
10922944501Smrg
11022944501Smrgtypedef struct _drm_intel_bufmgr_gem {
11122944501Smrg	drm_intel_bufmgr bufmgr;
11222944501Smrg
113a884aba1Smrg	atomic_t refcount;
114a884aba1Smrg
11522944501Smrg	int fd;
11622944501Smrg
11722944501Smrg	int max_relocs;
11822944501Smrg
11922944501Smrg	pthread_mutex_t lock;
12022944501Smrg
12122944501Smrg	struct drm_i915_gem_exec_object *exec_objects;
12222944501Smrg	struct drm_i915_gem_exec_object2 *exec2_objects;
12322944501Smrg	drm_intel_bo **exec_bos;
12422944501Smrg	int exec_size;
12522944501Smrg	int exec_count;
12622944501Smrg
12722944501Smrg	/** Array of lists of cached gem objects of power-of-two sizes */
128aaba2545Smrg	struct drm_intel_gem_bo_bucket cache_bucket[14 * 4];
129aaba2545Smrg	int num_buckets;
1306d98c517Smrg	time_t time;
13122944501Smrg
132a884aba1Smrg	drmMMListHead managers;
133a884aba1Smrg
13420131375Smrg	drmMMListHead named;
13520131375Smrg	drmMMListHead vma_cache;
13620131375Smrg	int vma_count, vma_open, vma_max;
13720131375Smrg
13822944501Smrg	uint64_t gtt_size;
13922944501Smrg	int available_fences;
14022944501Smrg	int pci_device;
14122944501Smrg	int gen;
1429ce4edccSmrg	unsigned int has_bsd : 1;
1439ce4edccSmrg	unsigned int has_blt : 1;
1449ce4edccSmrg	unsigned int has_relaxed_fencing : 1;
14520131375Smrg	unsigned int has_llc : 1;
14620131375Smrg	unsigned int has_wait_timeout : 1;
1479ce4edccSmrg	unsigned int bo_reuse : 1;
14820131375Smrg	unsigned int no_exec : 1;
14920131375Smrg	unsigned int has_vebox : 1;
15020131375Smrg	bool fenced_relocs;
15120131375Smrg
152424e9256Smrg	struct {
153424e9256Smrg		void *ptr;
154424e9256Smrg		uint32_t handle;
155424e9256Smrg	} userptr_active;
156424e9256Smrg
15722944501Smrg} drm_intel_bufmgr_gem;
15822944501Smrg
15922944501Smrg#define DRM_INTEL_RELOC_FENCE (1<<0)
16022944501Smrg
16122944501Smrgtypedef struct _drm_intel_reloc_target_info {
16222944501Smrg	drm_intel_bo *bo;
16322944501Smrg	int flags;
16422944501Smrg} drm_intel_reloc_target;
16522944501Smrg
16622944501Smrgstruct _drm_intel_bo_gem {
16722944501Smrg	drm_intel_bo bo;
16822944501Smrg
16922944501Smrg	atomic_t refcount;
17022944501Smrg	uint32_t gem_handle;
17122944501Smrg	const char *name;
17222944501Smrg
17322944501Smrg	/**
17422944501Smrg	 * Kenel-assigned global name for this object
17520131375Smrg         *
17620131375Smrg         * List contains both flink named and prime fd'd objects
17722944501Smrg	 */
17822944501Smrg	unsigned int global_name;
17920131375Smrg	drmMMListHead name_list;
18022944501Smrg
18122944501Smrg	/**
18222944501Smrg	 * Index of the buffer within the validation list while preparing a
18322944501Smrg	 * batchbuffer execution.
18422944501Smrg	 */
18522944501Smrg	int validate_index;
18622944501Smrg
18722944501Smrg	/**
18822944501Smrg	 * Current tiling mode
18922944501Smrg	 */
19022944501Smrg	uint32_t tiling_mode;
19122944501Smrg	uint32_t swizzle_mode;
1926d98c517Smrg	unsigned long stride;
19322944501Smrg
19422944501Smrg	time_t free_time;
19522944501Smrg
19622944501Smrg	/** Array passed to the DRM containing relocation information. */
19722944501Smrg	struct drm_i915_gem_relocation_entry *relocs;
19822944501Smrg	/**
19922944501Smrg	 * Array of info structs corresponding to relocs[i].target_handle etc
20022944501Smrg	 */
20122944501Smrg	drm_intel_reloc_target *reloc_target_info;
20222944501Smrg	/** Number of entries in relocs */
20322944501Smrg	int reloc_count;
204fe517fc9Smrg	/** Array of BOs that are referenced by this buffer and will be softpinned */
205fe517fc9Smrg	drm_intel_bo **softpin_target;
206fe517fc9Smrg	/** Number softpinned BOs that are referenced by this buffer */
207fe517fc9Smrg	int softpin_target_count;
208fe517fc9Smrg	/** Maximum amount of softpinned BOs that are referenced by this buffer */
209fe517fc9Smrg	int softpin_target_size;
210fe517fc9Smrg
21122944501Smrg	/** Mapped address for the buffer, saved across map/unmap cycles */
21222944501Smrg	void *mem_virtual;
21322944501Smrg	/** GTT virtual address for the buffer, saved across map/unmap cycles */
21422944501Smrg	void *gtt_virtual;
215a884aba1Smrg	/**
216a884aba1Smrg	 * Virtual address of the buffer allocated by user, used for userptr
217a884aba1Smrg	 * objects only.
218a884aba1Smrg	 */
219a884aba1Smrg	void *user_virtual;
22020131375Smrg	int map_count;
22120131375Smrg	drmMMListHead vma_list;
22222944501Smrg
22322944501Smrg	/** BO cache list */
22422944501Smrg	drmMMListHead head;
22522944501Smrg
22622944501Smrg	/**
22722944501Smrg	 * Boolean of whether this BO and its children have been included in
22822944501Smrg	 * the current drm_intel_bufmgr_check_aperture_space() total.
22922944501Smrg	 */
23020131375Smrg	bool included_in_check_aperture;
23122944501Smrg
23222944501Smrg	/**
23322944501Smrg	 * Boolean of whether this buffer has been used as a relocation
23422944501Smrg	 * target and had its size accounted for, and thus can't have any
23522944501Smrg	 * further relocations added to it.
23622944501Smrg	 */
23720131375Smrg	bool used_as_reloc_target;
23822944501Smrg
23922944501Smrg	/**
24022944501Smrg	 * Boolean of whether we have encountered an error whilst building the relocation tree.
24122944501Smrg	 */
24220131375Smrg	bool has_error;
24322944501Smrg
24422944501Smrg	/**
24522944501Smrg	 * Boolean of whether this buffer can be re-used
24622944501Smrg	 */
24720131375Smrg	bool reusable;
24820131375Smrg
24920131375Smrg	/**
25020131375Smrg	 * Boolean of whether the GPU is definitely not accessing the buffer.
25120131375Smrg	 *
25220131375Smrg	 * This is only valid when reusable, since non-reusable
25320131375Smrg	 * buffers are those that have been shared wth other
25420131375Smrg	 * processes, so we don't know their state.
25520131375Smrg	 */
25620131375Smrg	bool idle;
25722944501Smrg
258a884aba1Smrg	/**
259a884aba1Smrg	 * Boolean of whether this buffer was allocated with userptr
260a884aba1Smrg	 */
261a884aba1Smrg	bool is_userptr;
262a884aba1Smrg
263fe517fc9Smrg	/**
264fe517fc9Smrg	 * Boolean of whether this buffer can be placed in the full 48-bit
265fe517fc9Smrg	 * address range on gen8+.
266fe517fc9Smrg	 *
267fe517fc9Smrg	 * By default, buffers will be keep in a 32-bit range, unless this
268fe517fc9Smrg	 * flag is explicitly set.
269fe517fc9Smrg	 */
270fe517fc9Smrg	bool use_48b_address_range;
271fe517fc9Smrg
272fe517fc9Smrg	/**
273fe517fc9Smrg	 * Whether this buffer is softpinned at offset specified by the user
274fe517fc9Smrg	 */
275fe517fc9Smrg	bool is_softpin;
276fe517fc9Smrg
27722944501Smrg	/**
27822944501Smrg	 * Size in bytes of this buffer and its relocation descendents.
27922944501Smrg	 *
28022944501Smrg	 * Used to avoid costly tree walking in
28122944501Smrg	 * drm_intel_bufmgr_check_aperture in the common case.
28222944501Smrg	 */
28322944501Smrg	int reloc_tree_size;
28422944501Smrg
28522944501Smrg	/**
28622944501Smrg	 * Number of potential fence registers required by this buffer and its
28722944501Smrg	 * relocations.
28822944501Smrg	 */
28922944501Smrg	int reloc_tree_fences;
29020131375Smrg
29120131375Smrg	/** Flags that we may need to do the SW_FINSIH ioctl on unmap. */
29220131375Smrg	bool mapped_cpu_write;
29322944501Smrg};
29422944501Smrg
29522944501Smrgstatic unsigned int
29622944501Smrgdrm_intel_gem_estimate_batch_space(drm_intel_bo ** bo_array, int count);
29722944501Smrg
29822944501Smrgstatic unsigned int
29922944501Smrgdrm_intel_gem_compute_batch_space(drm_intel_bo ** bo_array, int count);
30022944501Smrg
30122944501Smrgstatic int
30222944501Smrgdrm_intel_gem_bo_get_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
30322944501Smrg			    uint32_t * swizzle_mode);
30422944501Smrg
30522944501Smrgstatic int
3066d98c517Smrgdrm_intel_gem_bo_set_tiling_internal(drm_intel_bo *bo,
3076d98c517Smrg				     uint32_t tiling_mode,
3086d98c517Smrg				     uint32_t stride);
30922944501Smrg
31022944501Smrgstatic void drm_intel_gem_bo_unreference_locked_timed(drm_intel_bo *bo,
31122944501Smrg						      time_t time);
31222944501Smrg
31322944501Smrgstatic void drm_intel_gem_bo_unreference(drm_intel_bo *bo);
31422944501Smrg
31522944501Smrgstatic void drm_intel_gem_bo_free(drm_intel_bo *bo);
31622944501Smrg
317fe517fc9Smrgstatic inline drm_intel_bo_gem *to_bo_gem(drm_intel_bo *bo)
318fe517fc9Smrg{
319fe517fc9Smrg        return (drm_intel_bo_gem *)bo;
320fe517fc9Smrg}
321fe517fc9Smrg
32222944501Smrgstatic unsigned long
32322944501Smrgdrm_intel_gem_bo_tile_size(drm_intel_bufmgr_gem *bufmgr_gem, unsigned long size,
32422944501Smrg			   uint32_t *tiling_mode)
32522944501Smrg{
32622944501Smrg	unsigned long min_size, max_size;
32722944501Smrg	unsigned long i;
32822944501Smrg
32922944501Smrg	if (*tiling_mode == I915_TILING_NONE)
33022944501Smrg		return size;
33122944501Smrg
33222944501Smrg	/* 965+ just need multiples of page size for tiling */
33322944501Smrg	if (bufmgr_gem->gen >= 4)
33422944501Smrg		return ROUND_UP_TO(size, 4096);
33522944501Smrg
33622944501Smrg	/* Older chips need powers of two, of at least 512k or 1M */
33722944501Smrg	if (bufmgr_gem->gen == 3) {
33822944501Smrg		min_size = 1024*1024;
33922944501Smrg		max_size = 128*1024*1024;
34022944501Smrg	} else {
34122944501Smrg		min_size = 512*1024;
34222944501Smrg		max_size = 64*1024*1024;
34322944501Smrg	}
34422944501Smrg
34522944501Smrg	if (size > max_size) {
34622944501Smrg		*tiling_mode = I915_TILING_NONE;
34722944501Smrg		return size;
34822944501Smrg	}
34922944501Smrg
3509ce4edccSmrg	/* Do we need to allocate every page for the fence? */
3519ce4edccSmrg	if (bufmgr_gem->has_relaxed_fencing)
3529ce4edccSmrg		return ROUND_UP_TO(size, 4096);
3539ce4edccSmrg
35422944501Smrg	for (i = min_size; i < size; i <<= 1)
35522944501Smrg		;
35622944501Smrg
35722944501Smrg	return i;
35822944501Smrg}
35922944501Smrg
36022944501Smrg/*
36122944501Smrg * Round a given pitch up to the minimum required for X tiling on a
36222944501Smrg * given chip.  We use 512 as the minimum to allow for a later tiling
36322944501Smrg * change.
36422944501Smrg */
36522944501Smrgstatic unsigned long
36622944501Smrgdrm_intel_gem_bo_tile_pitch(drm_intel_bufmgr_gem *bufmgr_gem,
3676d98c517Smrg			    unsigned long pitch, uint32_t *tiling_mode)
36822944501Smrg{
36922944501Smrg	unsigned long tile_width;
37022944501Smrg	unsigned long i;
37122944501Smrg
37222944501Smrg	/* If untiled, then just align it so that we can do rendering
37322944501Smrg	 * to it with the 3D engine.
37422944501Smrg	 */
3756d98c517Smrg	if (*tiling_mode == I915_TILING_NONE)
37622944501Smrg		return ALIGN(pitch, 64);
37722944501Smrg
37820131375Smrg	if (*tiling_mode == I915_TILING_X
37920131375Smrg			|| (IS_915(bufmgr_gem->pci_device)
38020131375Smrg			    && *tiling_mode == I915_TILING_Y))
38122944501Smrg		tile_width = 512;
38222944501Smrg	else
38322944501Smrg		tile_width = 128;
38422944501Smrg
38522944501Smrg	/* 965 is flexible */
38622944501Smrg	if (bufmgr_gem->gen >= 4)
38722944501Smrg		return ROUND_UP_TO(pitch, tile_width);
38822944501Smrg
3896d98c517Smrg	/* The older hardware has a maximum pitch of 8192 with tiled
3906d98c517Smrg	 * surfaces, so fallback to untiled if it's too large.
3916d98c517Smrg	 */
3926d98c517Smrg	if (pitch > 8192) {
3936d98c517Smrg		*tiling_mode = I915_TILING_NONE;
3946d98c517Smrg		return ALIGN(pitch, 64);
3956d98c517Smrg	}
3966d98c517Smrg
39722944501Smrg	/* Pre-965 needs power of two tile width */
39822944501Smrg	for (i = tile_width; i < pitch; i <<= 1)
39922944501Smrg		;
40022944501Smrg
40122944501Smrg	return i;
40222944501Smrg}
40322944501Smrg
40422944501Smrgstatic struct drm_intel_gem_bo_bucket *
40522944501Smrgdrm_intel_gem_bo_bucket_for_size(drm_intel_bufmgr_gem *bufmgr_gem,
40622944501Smrg				 unsigned long size)
40722944501Smrg{
40822944501Smrg	int i;
40922944501Smrg
410aaba2545Smrg	for (i = 0; i < bufmgr_gem->num_buckets; i++) {
41122944501Smrg		struct drm_intel_gem_bo_bucket *bucket =
41222944501Smrg		    &bufmgr_gem->cache_bucket[i];
41322944501Smrg		if (bucket->size >= size) {
41422944501Smrg			return bucket;
41522944501Smrg		}
41622944501Smrg	}
41722944501Smrg
41822944501Smrg	return NULL;
41922944501Smrg}
42022944501Smrg
42122944501Smrgstatic void
42222944501Smrgdrm_intel_gem_dump_validation_list(drm_intel_bufmgr_gem *bufmgr_gem)
42322944501Smrg{
42422944501Smrg	int i, j;
42522944501Smrg
42622944501Smrg	for (i = 0; i < bufmgr_gem->exec_count; i++) {
42722944501Smrg		drm_intel_bo *bo = bufmgr_gem->exec_bos[i];
42822944501Smrg		drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
42922944501Smrg
430fe517fc9Smrg		if (bo_gem->relocs == NULL && bo_gem->softpin_target == NULL) {
431fe517fc9Smrg			DBG("%2d: %d %s(%s)\n", i, bo_gem->gem_handle,
432fe517fc9Smrg			    bo_gem->is_softpin ? "*" : "",
43322944501Smrg			    bo_gem->name);
43422944501Smrg			continue;
43522944501Smrg		}
43622944501Smrg
43722944501Smrg		for (j = 0; j < bo_gem->reloc_count; j++) {
43822944501Smrg			drm_intel_bo *target_bo = bo_gem->reloc_target_info[j].bo;
43922944501Smrg			drm_intel_bo_gem *target_gem =
44022944501Smrg			    (drm_intel_bo_gem *) target_bo;
44122944501Smrg
442fe517fc9Smrg			DBG("%2d: %d %s(%s)@0x%08x %08x -> "
443fe517fc9Smrg			    "%d (%s)@0x%08x %08x + 0x%08x\n",
44422944501Smrg			    i,
445fe517fc9Smrg			    bo_gem->gem_handle,
446fe517fc9Smrg			    bo_gem->is_softpin ? "*" : "",
447fe517fc9Smrg			    bo_gem->name,
448fe517fc9Smrg			    upper_32_bits(bo_gem->relocs[j].offset),
449fe517fc9Smrg			    lower_32_bits(bo_gem->relocs[j].offset),
45022944501Smrg			    target_gem->gem_handle,
45122944501Smrg			    target_gem->name,
452fe517fc9Smrg			    upper_32_bits(target_bo->offset64),
453fe517fc9Smrg			    lower_32_bits(target_bo->offset64),
45422944501Smrg			    bo_gem->relocs[j].delta);
45522944501Smrg		}
456fe517fc9Smrg
457fe517fc9Smrg		for (j = 0; j < bo_gem->softpin_target_count; j++) {
458fe517fc9Smrg			drm_intel_bo *target_bo = bo_gem->softpin_target[j];
459fe517fc9Smrg			drm_intel_bo_gem *target_gem =
460fe517fc9Smrg			    (drm_intel_bo_gem *) target_bo;
461fe517fc9Smrg			DBG("%2d: %d %s(%s) -> "
462fe517fc9Smrg			    "%d *(%s)@0x%08x %08x\n",
463fe517fc9Smrg			    i,
464fe517fc9Smrg			    bo_gem->gem_handle,
465fe517fc9Smrg			    bo_gem->is_softpin ? "*" : "",
466fe517fc9Smrg			    bo_gem->name,
467fe517fc9Smrg			    target_gem->gem_handle,
468fe517fc9Smrg			    target_gem->name,
469fe517fc9Smrg			    upper_32_bits(target_bo->offset64),
470fe517fc9Smrg			    lower_32_bits(target_bo->offset64));
471fe517fc9Smrg		}
47222944501Smrg	}
47322944501Smrg}
47422944501Smrg
47522944501Smrgstatic inline void
47622944501Smrgdrm_intel_gem_bo_reference(drm_intel_bo *bo)
47722944501Smrg{
47822944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
47922944501Smrg
48022944501Smrg	atomic_inc(&bo_gem->refcount);
48122944501Smrg}
48222944501Smrg
48322944501Smrg/**
48422944501Smrg * Adds the given buffer to the list of buffers to be validated (moved into the
48522944501Smrg * appropriate memory type) with the next batch submission.
48622944501Smrg *
48722944501Smrg * If a buffer is validated multiple times in a batch submission, it ends up
48822944501Smrg * with the intersection of the memory type flags and the union of the
48922944501Smrg * access flags.
49022944501Smrg */
49122944501Smrgstatic void
49222944501Smrgdrm_intel_add_validate_buffer(drm_intel_bo *bo)
49322944501Smrg{
49422944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
49522944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
49622944501Smrg	int index;
49722944501Smrg
49822944501Smrg	if (bo_gem->validate_index != -1)
49922944501Smrg		return;
50022944501Smrg
50122944501Smrg	/* Extend the array of validation entries as necessary. */
50222944501Smrg	if (bufmgr_gem->exec_count == bufmgr_gem->exec_size) {
50322944501Smrg		int new_size = bufmgr_gem->exec_size * 2;
50422944501Smrg
50522944501Smrg		if (new_size == 0)
50622944501Smrg			new_size = 5;
50722944501Smrg
50822944501Smrg		bufmgr_gem->exec_objects =
50922944501Smrg		    realloc(bufmgr_gem->exec_objects,
51022944501Smrg			    sizeof(*bufmgr_gem->exec_objects) * new_size);
51122944501Smrg		bufmgr_gem->exec_bos =
51222944501Smrg		    realloc(bufmgr_gem->exec_bos,
51322944501Smrg			    sizeof(*bufmgr_gem->exec_bos) * new_size);
51422944501Smrg		bufmgr_gem->exec_size = new_size;
51522944501Smrg	}
51622944501Smrg
51722944501Smrg	index = bufmgr_gem->exec_count;
51822944501Smrg	bo_gem->validate_index = index;
51922944501Smrg	/* Fill in array entry */
52022944501Smrg	bufmgr_gem->exec_objects[index].handle = bo_gem->gem_handle;
52122944501Smrg	bufmgr_gem->exec_objects[index].relocation_count = bo_gem->reloc_count;
52222944501Smrg	bufmgr_gem->exec_objects[index].relocs_ptr = (uintptr_t) bo_gem->relocs;
523fe517fc9Smrg	bufmgr_gem->exec_objects[index].alignment = bo->align;
52422944501Smrg	bufmgr_gem->exec_objects[index].offset = 0;
52522944501Smrg	bufmgr_gem->exec_bos[index] = bo;
52622944501Smrg	bufmgr_gem->exec_count++;
52722944501Smrg}
52822944501Smrg
52922944501Smrgstatic void
53022944501Smrgdrm_intel_add_validate_buffer2(drm_intel_bo *bo, int need_fence)
53122944501Smrg{
53222944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo->bufmgr;
53322944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
53422944501Smrg	int index;
535fe517fc9Smrg	int flags = 0;
536fe517fc9Smrg
537fe517fc9Smrg	if (need_fence)
538fe517fc9Smrg		flags |= EXEC_OBJECT_NEEDS_FENCE;
539fe517fc9Smrg	if (bo_gem->use_48b_address_range)
540fe517fc9Smrg		flags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
541fe517fc9Smrg	if (bo_gem->is_softpin)
542fe517fc9Smrg		flags |= EXEC_OBJECT_PINNED;
54322944501Smrg
54422944501Smrg	if (bo_gem->validate_index != -1) {
545fe517fc9Smrg		bufmgr_gem->exec2_objects[bo_gem->validate_index].flags |= flags;
54622944501Smrg		return;
54722944501Smrg	}
54822944501Smrg
54922944501Smrg	/* Extend the array of validation entries as necessary. */
55022944501Smrg	if (bufmgr_gem->exec_count == bufmgr_gem->exec_size) {
55122944501Smrg		int new_size = bufmgr_gem->exec_size * 2;
55222944501Smrg
55322944501Smrg		if (new_size == 0)
55422944501Smrg			new_size = 5;
55522944501Smrg
55622944501Smrg		bufmgr_gem->exec2_objects =
55722944501Smrg			realloc(bufmgr_gem->exec2_objects,
55822944501Smrg				sizeof(*bufmgr_gem->exec2_objects) * new_size);
55922944501Smrg		bufmgr_gem->exec_bos =
56022944501Smrg			realloc(bufmgr_gem->exec_bos,
56122944501Smrg				sizeof(*bufmgr_gem->exec_bos) * new_size);
56222944501Smrg		bufmgr_gem->exec_size = new_size;
56322944501Smrg	}
56422944501Smrg
56522944501Smrg	index = bufmgr_gem->exec_count;
56622944501Smrg	bo_gem->validate_index = index;
56722944501Smrg	/* Fill in array entry */
56822944501Smrg	bufmgr_gem->exec2_objects[index].handle = bo_gem->gem_handle;
56922944501Smrg	bufmgr_gem->exec2_objects[index].relocation_count = bo_gem->reloc_count;
57022944501Smrg	bufmgr_gem->exec2_objects[index].relocs_ptr = (uintptr_t)bo_gem->relocs;
571fe517fc9Smrg	bufmgr_gem->exec2_objects[index].alignment = bo->align;
572fe517fc9Smrg	bufmgr_gem->exec2_objects[index].offset = bo_gem->is_softpin ?
573fe517fc9Smrg		bo->offset64 : 0;
57422944501Smrg	bufmgr_gem->exec_bos[index] = bo;
575fe517fc9Smrg	bufmgr_gem->exec2_objects[index].flags = flags;
57622944501Smrg	bufmgr_gem->exec2_objects[index].rsvd1 = 0;
57722944501Smrg	bufmgr_gem->exec2_objects[index].rsvd2 = 0;
57822944501Smrg	bufmgr_gem->exec_count++;
57922944501Smrg}
58022944501Smrg
58122944501Smrg#define RELOC_BUF_SIZE(x) ((I915_RELOC_HEADER + x * I915_RELOC0_STRIDE) * \
58222944501Smrg	sizeof(uint32_t))
58322944501Smrg
58422944501Smrgstatic void
58522944501Smrgdrm_intel_bo_gem_set_in_aperture_size(drm_intel_bufmgr_gem *bufmgr_gem,
586fe517fc9Smrg				      drm_intel_bo_gem *bo_gem,
587fe517fc9Smrg				      unsigned int alignment)
58822944501Smrg{
589fe517fc9Smrg	unsigned int size;
59022944501Smrg
59122944501Smrg	assert(!bo_gem->used_as_reloc_target);
59222944501Smrg
59322944501Smrg	/* The older chipsets are far-less flexible in terms of tiling,
59422944501Smrg	 * and require tiled buffer to be size aligned in the aperture.
59522944501Smrg	 * This means that in the worst possible case we will need a hole
59622944501Smrg	 * twice as large as the object in order for it to fit into the
59722944501Smrg	 * aperture. Optimal packing is for wimps.
59822944501Smrg	 */
59922944501Smrg	size = bo_gem->bo.size;
6009ce4edccSmrg	if (bufmgr_gem->gen < 4 && bo_gem->tiling_mode != I915_TILING_NONE) {
601fe517fc9Smrg		unsigned int min_size;
6029ce4edccSmrg
6039ce4edccSmrg		if (bufmgr_gem->has_relaxed_fencing) {
6049ce4edccSmrg			if (bufmgr_gem->gen == 3)
6059ce4edccSmrg				min_size = 1024*1024;
6069ce4edccSmrg			else
6079ce4edccSmrg				min_size = 512*1024;
6089ce4edccSmrg
6099ce4edccSmrg			while (min_size < size)
6109ce4edccSmrg				min_size *= 2;
6119ce4edccSmrg		} else
6129ce4edccSmrg			min_size = size;
6139ce4edccSmrg
6149ce4edccSmrg		/* Account for worst-case alignment. */
615fe517fc9Smrg		alignment = MAX2(alignment, min_size);
6169ce4edccSmrg	}
61722944501Smrg
618fe517fc9Smrg	bo_gem->reloc_tree_size = size + alignment;
61922944501Smrg}
62022944501Smrg
62122944501Smrgstatic int
62222944501Smrgdrm_intel_setup_reloc_list(drm_intel_bo *bo)
62322944501Smrg{
62422944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
62522944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
62622944501Smrg	unsigned int max_relocs = bufmgr_gem->max_relocs;
62722944501Smrg
62822944501Smrg	if (bo->size / 4 < max_relocs)
62922944501Smrg		max_relocs = bo->size / 4;
63022944501Smrg
63122944501Smrg	bo_gem->relocs = malloc(max_relocs *
63222944501Smrg				sizeof(struct drm_i915_gem_relocation_entry));
63322944501Smrg	bo_gem->reloc_target_info = malloc(max_relocs *
634aaba2545Smrg					   sizeof(drm_intel_reloc_target));
63522944501Smrg	if (bo_gem->relocs == NULL || bo_gem->reloc_target_info == NULL) {
63620131375Smrg		bo_gem->has_error = true;
63722944501Smrg
63822944501Smrg		free (bo_gem->relocs);
63922944501Smrg		bo_gem->relocs = NULL;
64022944501Smrg
64122944501Smrg		free (bo_gem->reloc_target_info);
64222944501Smrg		bo_gem->reloc_target_info = NULL;
64322944501Smrg
64422944501Smrg		return 1;
64522944501Smrg	}
64622944501Smrg
64722944501Smrg	return 0;
64822944501Smrg}
64922944501Smrg
65022944501Smrgstatic int
65122944501Smrgdrm_intel_gem_bo_busy(drm_intel_bo *bo)
65222944501Smrg{
65322944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
65422944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
65522944501Smrg	struct drm_i915_gem_busy busy;
65622944501Smrg	int ret;
65722944501Smrg
65820131375Smrg	if (bo_gem->reusable && bo_gem->idle)
65920131375Smrg		return false;
66020131375Smrg
661424e9256Smrg	memclear(busy);
66222944501Smrg	busy.handle = bo_gem->gem_handle;
66322944501Smrg
6646d98c517Smrg	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
66520131375Smrg	if (ret == 0) {
66620131375Smrg		bo_gem->idle = !busy.busy;
66720131375Smrg		return busy.busy;
66820131375Smrg	} else {
66920131375Smrg		return false;
67020131375Smrg	}
67122944501Smrg	return (ret == 0 && busy.busy);
67222944501Smrg}
67322944501Smrg
67422944501Smrgstatic int
67522944501Smrgdrm_intel_gem_bo_madvise_internal(drm_intel_bufmgr_gem *bufmgr_gem,
67622944501Smrg				  drm_intel_bo_gem *bo_gem, int state)
67722944501Smrg{
67822944501Smrg	struct drm_i915_gem_madvise madv;
67922944501Smrg
680424e9256Smrg	memclear(madv);
68122944501Smrg	madv.handle = bo_gem->gem_handle;
68222944501Smrg	madv.madv = state;
68322944501Smrg	madv.retained = 1;
6846d98c517Smrg	drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv);
68522944501Smrg
68622944501Smrg	return madv.retained;
68722944501Smrg}
68822944501Smrg
68922944501Smrgstatic int
69022944501Smrgdrm_intel_gem_bo_madvise(drm_intel_bo *bo, int madv)
69122944501Smrg{
69222944501Smrg	return drm_intel_gem_bo_madvise_internal
69322944501Smrg		((drm_intel_bufmgr_gem *) bo->bufmgr,
69422944501Smrg		 (drm_intel_bo_gem *) bo,
69522944501Smrg		 madv);
69622944501Smrg}
69722944501Smrg
69822944501Smrg/* drop the oldest entries that have been purged by the kernel */
69922944501Smrgstatic void
70022944501Smrgdrm_intel_gem_bo_cache_purge_bucket(drm_intel_bufmgr_gem *bufmgr_gem,
70122944501Smrg				    struct drm_intel_gem_bo_bucket *bucket)
70222944501Smrg{
70322944501Smrg	while (!DRMLISTEMPTY(&bucket->head)) {
70422944501Smrg		drm_intel_bo_gem *bo_gem;
70522944501Smrg
70622944501Smrg		bo_gem = DRMLISTENTRY(drm_intel_bo_gem,
70722944501Smrg				      bucket->head.next, head);
70822944501Smrg		if (drm_intel_gem_bo_madvise_internal
70922944501Smrg		    (bufmgr_gem, bo_gem, I915_MADV_DONTNEED))
71022944501Smrg			break;
71122944501Smrg
71222944501Smrg		DRMLISTDEL(&bo_gem->head);
71322944501Smrg		drm_intel_gem_bo_free(&bo_gem->bo);
71422944501Smrg	}
71522944501Smrg}
71622944501Smrg
71722944501Smrgstatic drm_intel_bo *
71822944501Smrgdrm_intel_gem_bo_alloc_internal(drm_intel_bufmgr *bufmgr,
71922944501Smrg				const char *name,
72022944501Smrg				unsigned long size,
7216d98c517Smrg				unsigned long flags,
7226d98c517Smrg				uint32_t tiling_mode,
723fe517fc9Smrg				unsigned long stride,
724fe517fc9Smrg				unsigned int alignment)
72522944501Smrg{
72622944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
72722944501Smrg	drm_intel_bo_gem *bo_gem;
72822944501Smrg	unsigned int page_size = getpagesize();
72922944501Smrg	int ret;
73022944501Smrg	struct drm_intel_gem_bo_bucket *bucket;
73120131375Smrg	bool alloc_from_cache;
73222944501Smrg	unsigned long bo_size;
73320131375Smrg	bool for_render = false;
73422944501Smrg
73522944501Smrg	if (flags & BO_ALLOC_FOR_RENDER)
73620131375Smrg		for_render = true;
73722944501Smrg
73822944501Smrg	/* Round the allocated size up to a power of two number of pages. */
73922944501Smrg	bucket = drm_intel_gem_bo_bucket_for_size(bufmgr_gem, size);
74022944501Smrg
74122944501Smrg	/* If we don't have caching at this size, don't actually round the
74222944501Smrg	 * allocation up.
74322944501Smrg	 */
74422944501Smrg	if (bucket == NULL) {
74522944501Smrg		bo_size = size;
74622944501Smrg		if (bo_size < page_size)
74722944501Smrg			bo_size = page_size;
74822944501Smrg	} else {
74922944501Smrg		bo_size = bucket->size;
75022944501Smrg	}
75122944501Smrg
75222944501Smrg	pthread_mutex_lock(&bufmgr_gem->lock);
75322944501Smrg	/* Get a buffer out of the cache if available */
75422944501Smrgretry:
75520131375Smrg	alloc_from_cache = false;
75622944501Smrg	if (bucket != NULL && !DRMLISTEMPTY(&bucket->head)) {
75722944501Smrg		if (for_render) {
75822944501Smrg			/* Allocate new render-target BOs from the tail (MRU)
75922944501Smrg			 * of the list, as it will likely be hot in the GPU
76022944501Smrg			 * cache and in the aperture for us.
76122944501Smrg			 */
76222944501Smrg			bo_gem = DRMLISTENTRY(drm_intel_bo_gem,
76322944501Smrg					      bucket->head.prev, head);
76422944501Smrg			DRMLISTDEL(&bo_gem->head);
76520131375Smrg			alloc_from_cache = true;
766fe517fc9Smrg			bo_gem->bo.align = alignment;
76722944501Smrg		} else {
768fe517fc9Smrg			assert(alignment == 0);
76922944501Smrg			/* For non-render-target BOs (where we're probably
77022944501Smrg			 * going to map it first thing in order to fill it
77122944501Smrg			 * with data), check if the last BO in the cache is
77222944501Smrg			 * unbusy, and only reuse in that case. Otherwise,
77322944501Smrg			 * allocating a new buffer is probably faster than
77422944501Smrg			 * waiting for the GPU to finish.
77522944501Smrg			 */
77622944501Smrg			bo_gem = DRMLISTENTRY(drm_intel_bo_gem,
77722944501Smrg					      bucket->head.next, head);
77822944501Smrg			if (!drm_intel_gem_bo_busy(&bo_gem->bo)) {
77920131375Smrg				alloc_from_cache = true;
78022944501Smrg				DRMLISTDEL(&bo_gem->head);
78122944501Smrg			}
78222944501Smrg		}
78322944501Smrg
78422944501Smrg		if (alloc_from_cache) {
78522944501Smrg			if (!drm_intel_gem_bo_madvise_internal
78622944501Smrg			    (bufmgr_gem, bo_gem, I915_MADV_WILLNEED)) {
78722944501Smrg				drm_intel_gem_bo_free(&bo_gem->bo);
78822944501Smrg				drm_intel_gem_bo_cache_purge_bucket(bufmgr_gem,
78922944501Smrg								    bucket);
79022944501Smrg				goto retry;
79122944501Smrg			}
7926d98c517Smrg
7936d98c517Smrg			if (drm_intel_gem_bo_set_tiling_internal(&bo_gem->bo,
7946d98c517Smrg								 tiling_mode,
7956d98c517Smrg								 stride)) {
7966d98c517Smrg				drm_intel_gem_bo_free(&bo_gem->bo);
7976d98c517Smrg				goto retry;
7986d98c517Smrg			}
79922944501Smrg		}
80022944501Smrg	}
80122944501Smrg	pthread_mutex_unlock(&bufmgr_gem->lock);
80222944501Smrg
80322944501Smrg	if (!alloc_from_cache) {
80422944501Smrg		struct drm_i915_gem_create create;
80522944501Smrg
80622944501Smrg		bo_gem = calloc(1, sizeof(*bo_gem));
80722944501Smrg		if (!bo_gem)
80822944501Smrg			return NULL;
80922944501Smrg
81022944501Smrg		bo_gem->bo.size = bo_size;
81120131375Smrg
812424e9256Smrg		memclear(create);
81322944501Smrg		create.size = bo_size;
81422944501Smrg
8156d98c517Smrg		ret = drmIoctl(bufmgr_gem->fd,
8166d98c517Smrg			       DRM_IOCTL_I915_GEM_CREATE,
8176d98c517Smrg			       &create);
81822944501Smrg		bo_gem->gem_handle = create.handle;
81922944501Smrg		bo_gem->bo.handle = bo_gem->gem_handle;
82022944501Smrg		if (ret != 0) {
82122944501Smrg			free(bo_gem);
82222944501Smrg			return NULL;
82322944501Smrg		}
82422944501Smrg		bo_gem->bo.bufmgr = bufmgr;
825fe517fc9Smrg		bo_gem->bo.align = alignment;
8266d98c517Smrg
8276d98c517Smrg		bo_gem->tiling_mode = I915_TILING_NONE;
8286d98c517Smrg		bo_gem->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
8296d98c517Smrg		bo_gem->stride = 0;
8306d98c517Smrg
8313c748557Ssnj		/* drm_intel_gem_bo_free calls DRMLISTDEL() for an uninitialized
8323c748557Ssnj		   list (vma_list), so better set the list head here */
8333c748557Ssnj		DRMINITLISTHEAD(&bo_gem->name_list);
8343c748557Ssnj		DRMINITLISTHEAD(&bo_gem->vma_list);
8356d98c517Smrg		if (drm_intel_gem_bo_set_tiling_internal(&bo_gem->bo,
8366d98c517Smrg							 tiling_mode,
8376d98c517Smrg							 stride)) {
8386d98c517Smrg		    drm_intel_gem_bo_free(&bo_gem->bo);
8396d98c517Smrg		    return NULL;
8406d98c517Smrg		}
84122944501Smrg	}
84222944501Smrg
84322944501Smrg	bo_gem->name = name;
84422944501Smrg	atomic_set(&bo_gem->refcount, 1);
84522944501Smrg	bo_gem->validate_index = -1;
84622944501Smrg	bo_gem->reloc_tree_fences = 0;
84720131375Smrg	bo_gem->used_as_reloc_target = false;
84820131375Smrg	bo_gem->has_error = false;
84920131375Smrg	bo_gem->reusable = true;
850fe517fc9Smrg	bo_gem->use_48b_address_range = false;
85122944501Smrg
852fe517fc9Smrg	drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, alignment);
85322944501Smrg
85422944501Smrg	DBG("bo_create: buf %d (%s) %ldb\n",
85522944501Smrg	    bo_gem->gem_handle, bo_gem->name, size);
85622944501Smrg
85722944501Smrg	return &bo_gem->bo;
85822944501Smrg}
85922944501Smrg
86022944501Smrgstatic drm_intel_bo *
86122944501Smrgdrm_intel_gem_bo_alloc_for_render(drm_intel_bufmgr *bufmgr,
86222944501Smrg				  const char *name,
86322944501Smrg				  unsigned long size,
86422944501Smrg				  unsigned int alignment)
86522944501Smrg{
86622944501Smrg	return drm_intel_gem_bo_alloc_internal(bufmgr, name, size,
8676d98c517Smrg					       BO_ALLOC_FOR_RENDER,
868fe517fc9Smrg					       I915_TILING_NONE, 0,
869fe517fc9Smrg					       alignment);
87022944501Smrg}
87122944501Smrg
87222944501Smrgstatic drm_intel_bo *
87322944501Smrgdrm_intel_gem_bo_alloc(drm_intel_bufmgr *bufmgr,
87422944501Smrg		       const char *name,
87522944501Smrg		       unsigned long size,
87622944501Smrg		       unsigned int alignment)
87722944501Smrg{
8786d98c517Smrg	return drm_intel_gem_bo_alloc_internal(bufmgr, name, size, 0,
879fe517fc9Smrg					       I915_TILING_NONE, 0, 0);
88022944501Smrg}
88122944501Smrg
88222944501Smrgstatic drm_intel_bo *
88322944501Smrgdrm_intel_gem_bo_alloc_tiled(drm_intel_bufmgr *bufmgr, const char *name,
88422944501Smrg			     int x, int y, int cpp, uint32_t *tiling_mode,
88522944501Smrg			     unsigned long *pitch, unsigned long flags)
88622944501Smrg{
88722944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
888aaba2545Smrg	unsigned long size, stride;
889aaba2545Smrg	uint32_t tiling;
89022944501Smrg
891aaba2545Smrg	do {
89220131375Smrg		unsigned long aligned_y, height_alignment;
893aaba2545Smrg
894aaba2545Smrg		tiling = *tiling_mode;
895aaba2545Smrg
896aaba2545Smrg		/* If we're tiled, our allocations are in 8 or 32-row blocks,
897aaba2545Smrg		 * so failure to align our height means that we won't allocate
898aaba2545Smrg		 * enough pages.
899aaba2545Smrg		 *
900aaba2545Smrg		 * If we're untiled, we still have to align to 2 rows high
901aaba2545Smrg		 * because the data port accesses 2x2 blocks even if the
902aaba2545Smrg		 * bottom row isn't to be rendered, so failure to align means
903aaba2545Smrg		 * we could walk off the end of the GTT and fault.  This is
904aaba2545Smrg		 * documented on 965, and may be the case on older chipsets
905aaba2545Smrg		 * too so we try to be careful.
906aaba2545Smrg		 */
907aaba2545Smrg		aligned_y = y;
90820131375Smrg		height_alignment = 2;
90920131375Smrg
91020131375Smrg		if ((bufmgr_gem->gen == 2) && tiling != I915_TILING_NONE)
91120131375Smrg			height_alignment = 16;
91220131375Smrg		else if (tiling == I915_TILING_X
91320131375Smrg			|| (IS_915(bufmgr_gem->pci_device)
91420131375Smrg			    && tiling == I915_TILING_Y))
91520131375Smrg			height_alignment = 8;
916aaba2545Smrg		else if (tiling == I915_TILING_Y)
91720131375Smrg			height_alignment = 32;
91820131375Smrg		aligned_y = ALIGN(y, height_alignment);
919aaba2545Smrg
920aaba2545Smrg		stride = x * cpp;
9216d98c517Smrg		stride = drm_intel_gem_bo_tile_pitch(bufmgr_gem, stride, tiling_mode);
922aaba2545Smrg		size = stride * aligned_y;
923aaba2545Smrg		size = drm_intel_gem_bo_tile_size(bufmgr_gem, size, tiling_mode);
924aaba2545Smrg	} while (*tiling_mode != tiling);
92522944501Smrg	*pitch = stride;
92622944501Smrg
9276d98c517Smrg	if (tiling == I915_TILING_NONE)
9286d98c517Smrg		stride = 0;
9296d98c517Smrg
9306d98c517Smrg	return drm_intel_gem_bo_alloc_internal(bufmgr, name, size, flags,
931fe517fc9Smrg					       tiling, stride, 0);
93222944501Smrg}
93322944501Smrg
934a884aba1Smrgstatic drm_intel_bo *
935a884aba1Smrgdrm_intel_gem_bo_alloc_userptr(drm_intel_bufmgr *bufmgr,
936a884aba1Smrg				const char *name,
937a884aba1Smrg				void *addr,
938a884aba1Smrg				uint32_t tiling_mode,
939a884aba1Smrg				uint32_t stride,
940a884aba1Smrg				unsigned long size,
941a884aba1Smrg				unsigned long flags)
942a884aba1Smrg{
943a884aba1Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
944a884aba1Smrg	drm_intel_bo_gem *bo_gem;
945a884aba1Smrg	int ret;
946a884aba1Smrg	struct drm_i915_gem_userptr userptr;
947a884aba1Smrg
948a884aba1Smrg	/* Tiling with userptr surfaces is not supported
949a884aba1Smrg	 * on all hardware so refuse it for time being.
950a884aba1Smrg	 */
951a884aba1Smrg	if (tiling_mode != I915_TILING_NONE)
952a884aba1Smrg		return NULL;
953a884aba1Smrg
954a884aba1Smrg	bo_gem = calloc(1, sizeof(*bo_gem));
955a884aba1Smrg	if (!bo_gem)
956a884aba1Smrg		return NULL;
957a884aba1Smrg
958a884aba1Smrg	bo_gem->bo.size = size;
959a884aba1Smrg
960424e9256Smrg	memclear(userptr);
961a884aba1Smrg	userptr.user_ptr = (__u64)((unsigned long)addr);
962a884aba1Smrg	userptr.user_size = size;
963a884aba1Smrg	userptr.flags = flags;
964a884aba1Smrg
965a884aba1Smrg	ret = drmIoctl(bufmgr_gem->fd,
966a884aba1Smrg			DRM_IOCTL_I915_GEM_USERPTR,
967a884aba1Smrg			&userptr);
968a884aba1Smrg	if (ret != 0) {
969a884aba1Smrg		DBG("bo_create_userptr: "
970a884aba1Smrg		    "ioctl failed with user ptr %p size 0x%lx, "
971a884aba1Smrg		    "user flags 0x%lx\n", addr, size, flags);
972a884aba1Smrg		free(bo_gem);
973a884aba1Smrg		return NULL;
974a884aba1Smrg	}
975a884aba1Smrg
976a884aba1Smrg	bo_gem->gem_handle = userptr.handle;
977a884aba1Smrg	bo_gem->bo.handle = bo_gem->gem_handle;
978a884aba1Smrg	bo_gem->bo.bufmgr    = bufmgr;
979a884aba1Smrg	bo_gem->is_userptr   = true;
980a884aba1Smrg	bo_gem->bo.virtual   = addr;
981a884aba1Smrg	/* Save the address provided by user */
982a884aba1Smrg	bo_gem->user_virtual = addr;
983a884aba1Smrg	bo_gem->tiling_mode  = I915_TILING_NONE;
984a884aba1Smrg	bo_gem->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
985a884aba1Smrg	bo_gem->stride       = 0;
986a884aba1Smrg
987a884aba1Smrg	DRMINITLISTHEAD(&bo_gem->name_list);
988a884aba1Smrg	DRMINITLISTHEAD(&bo_gem->vma_list);
989a884aba1Smrg
990a884aba1Smrg	bo_gem->name = name;
991a884aba1Smrg	atomic_set(&bo_gem->refcount, 1);
992a884aba1Smrg	bo_gem->validate_index = -1;
993a884aba1Smrg	bo_gem->reloc_tree_fences = 0;
994a884aba1Smrg	bo_gem->used_as_reloc_target = false;
995a884aba1Smrg	bo_gem->has_error = false;
996a884aba1Smrg	bo_gem->reusable = false;
997fe517fc9Smrg	bo_gem->use_48b_address_range = false;
998a884aba1Smrg
999fe517fc9Smrg	drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, 0);
1000a884aba1Smrg
1001a884aba1Smrg	DBG("bo_create_userptr: "
1002a884aba1Smrg	    "ptr %p buf %d (%s) size %ldb, stride 0x%x, tile mode %d\n",
1003a884aba1Smrg		addr, bo_gem->gem_handle, bo_gem->name,
1004a884aba1Smrg		size, stride, tiling_mode);
1005a884aba1Smrg
1006a884aba1Smrg	return &bo_gem->bo;
1007a884aba1Smrg}
1008a884aba1Smrg
1009424e9256Smrgstatic bool
1010424e9256Smrghas_userptr(drm_intel_bufmgr_gem *bufmgr_gem)
1011424e9256Smrg{
1012424e9256Smrg	int ret;
1013424e9256Smrg	void *ptr;
1014424e9256Smrg	long pgsz;
1015424e9256Smrg	struct drm_i915_gem_userptr userptr;
1016424e9256Smrg
1017424e9256Smrg	pgsz = sysconf(_SC_PAGESIZE);
1018424e9256Smrg	assert(pgsz > 0);
1019424e9256Smrg
1020424e9256Smrg	ret = posix_memalign(&ptr, pgsz, pgsz);
1021424e9256Smrg	if (ret) {
1022424e9256Smrg		DBG("Failed to get a page (%ld) for userptr detection!\n",
1023424e9256Smrg			pgsz);
1024424e9256Smrg		return false;
1025424e9256Smrg	}
1026424e9256Smrg
1027424e9256Smrg	memclear(userptr);
1028424e9256Smrg	userptr.user_ptr = (__u64)(unsigned long)ptr;
1029424e9256Smrg	userptr.user_size = pgsz;
1030424e9256Smrg
1031424e9256Smrgretry:
1032424e9256Smrg	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_USERPTR, &userptr);
1033424e9256Smrg	if (ret) {
1034424e9256Smrg		if (errno == ENODEV && userptr.flags == 0) {
1035424e9256Smrg			userptr.flags = I915_USERPTR_UNSYNCHRONIZED;
1036424e9256Smrg			goto retry;
1037424e9256Smrg		}
1038424e9256Smrg		free(ptr);
1039424e9256Smrg		return false;
1040424e9256Smrg	}
1041424e9256Smrg
1042424e9256Smrg	/* We don't release the userptr bo here as we want to keep the
1043424e9256Smrg	 * kernel mm tracking alive for our lifetime. The first time we
1044424e9256Smrg	 * create a userptr object the kernel has to install a mmu_notifer
1045424e9256Smrg	 * which is a heavyweight operation (e.g. it requires taking all
1046424e9256Smrg	 * mm_locks and stop_machine()).
1047424e9256Smrg	 */
1048424e9256Smrg
1049424e9256Smrg	bufmgr_gem->userptr_active.ptr = ptr;
1050424e9256Smrg	bufmgr_gem->userptr_active.handle = userptr.handle;
1051424e9256Smrg
1052424e9256Smrg	return true;
1053424e9256Smrg}
1054424e9256Smrg
1055424e9256Smrgstatic drm_intel_bo *
1056424e9256Smrgcheck_bo_alloc_userptr(drm_intel_bufmgr *bufmgr,
1057424e9256Smrg		       const char *name,
1058424e9256Smrg		       void *addr,
1059424e9256Smrg		       uint32_t tiling_mode,
1060424e9256Smrg		       uint32_t stride,
1061424e9256Smrg		       unsigned long size,
1062424e9256Smrg		       unsigned long flags)
1063424e9256Smrg{
1064424e9256Smrg	if (has_userptr((drm_intel_bufmgr_gem *)bufmgr))
1065424e9256Smrg		bufmgr->bo_alloc_userptr = drm_intel_gem_bo_alloc_userptr;
1066424e9256Smrg	else
1067424e9256Smrg		bufmgr->bo_alloc_userptr = NULL;
1068424e9256Smrg
1069424e9256Smrg	return drm_intel_bo_alloc_userptr(bufmgr, name, addr,
1070424e9256Smrg					  tiling_mode, stride, size, flags);
1071424e9256Smrg}
1072424e9256Smrg
107322944501Smrg/**
107422944501Smrg * Returns a drm_intel_bo wrapping the given buffer object handle.
107522944501Smrg *
107622944501Smrg * This can be used when one application needs to pass a buffer object
107722944501Smrg * to another.
107822944501Smrg */
1079424e9256Smrgdrm_intel_bo *
108022944501Smrgdrm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr,
108122944501Smrg				  const char *name,
108222944501Smrg				  unsigned int handle)
108322944501Smrg{
108422944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
108522944501Smrg	drm_intel_bo_gem *bo_gem;
108622944501Smrg	int ret;
108722944501Smrg	struct drm_gem_open open_arg;
108822944501Smrg	struct drm_i915_gem_get_tiling get_tiling;
108920131375Smrg	drmMMListHead *list;
109022944501Smrg
109120131375Smrg	/* At the moment most applications only have a few named bo.
109220131375Smrg	 * For instance, in a DRI client only the render buffers passed
109320131375Smrg	 * between X and the client are named. And since X returns the
109420131375Smrg	 * alternating names for the front/back buffer a linear search
109520131375Smrg	 * provides a sufficiently fast match.
109620131375Smrg	 */
1097a884aba1Smrg	pthread_mutex_lock(&bufmgr_gem->lock);
109820131375Smrg	for (list = bufmgr_gem->named.next;
109920131375Smrg	     list != &bufmgr_gem->named;
110020131375Smrg	     list = list->next) {
110120131375Smrg		bo_gem = DRMLISTENTRY(drm_intel_bo_gem, list, name_list);
110220131375Smrg		if (bo_gem->global_name == handle) {
110320131375Smrg			drm_intel_gem_bo_reference(&bo_gem->bo);
1104a884aba1Smrg			pthread_mutex_unlock(&bufmgr_gem->lock);
110520131375Smrg			return &bo_gem->bo;
110620131375Smrg		}
110720131375Smrg	}
110822944501Smrg
1109424e9256Smrg	memclear(open_arg);
111022944501Smrg	open_arg.name = handle;
11116d98c517Smrg	ret = drmIoctl(bufmgr_gem->fd,
11126d98c517Smrg		       DRM_IOCTL_GEM_OPEN,
11136d98c517Smrg		       &open_arg);
111422944501Smrg	if (ret != 0) {
11159ce4edccSmrg		DBG("Couldn't reference %s handle 0x%08x: %s\n",
11169ce4edccSmrg		    name, handle, strerror(errno));
1117a884aba1Smrg		pthread_mutex_unlock(&bufmgr_gem->lock);
111822944501Smrg		return NULL;
111922944501Smrg	}
112020131375Smrg        /* Now see if someone has used a prime handle to get this
112120131375Smrg         * object from the kernel before by looking through the list
112220131375Smrg         * again for a matching gem_handle
112320131375Smrg         */
112420131375Smrg	for (list = bufmgr_gem->named.next;
112520131375Smrg	     list != &bufmgr_gem->named;
112620131375Smrg	     list = list->next) {
112720131375Smrg		bo_gem = DRMLISTENTRY(drm_intel_bo_gem, list, name_list);
112820131375Smrg		if (bo_gem->gem_handle == open_arg.handle) {
112920131375Smrg			drm_intel_gem_bo_reference(&bo_gem->bo);
1130a884aba1Smrg			pthread_mutex_unlock(&bufmgr_gem->lock);
113120131375Smrg			return &bo_gem->bo;
113220131375Smrg		}
113320131375Smrg	}
113420131375Smrg
113520131375Smrg	bo_gem = calloc(1, sizeof(*bo_gem));
1136a884aba1Smrg	if (!bo_gem) {
1137a884aba1Smrg		pthread_mutex_unlock(&bufmgr_gem->lock);
113820131375Smrg		return NULL;
1139a884aba1Smrg	}
114020131375Smrg
114122944501Smrg	bo_gem->bo.size = open_arg.size;
114222944501Smrg	bo_gem->bo.offset = 0;
114320131375Smrg	bo_gem->bo.offset64 = 0;
114422944501Smrg	bo_gem->bo.virtual = NULL;
114522944501Smrg	bo_gem->bo.bufmgr = bufmgr;
114622944501Smrg	bo_gem->name = name;
114722944501Smrg	atomic_set(&bo_gem->refcount, 1);
114822944501Smrg	bo_gem->validate_index = -1;
114922944501Smrg	bo_gem->gem_handle = open_arg.handle;
115020131375Smrg	bo_gem->bo.handle = open_arg.handle;
115122944501Smrg	bo_gem->global_name = handle;
115220131375Smrg	bo_gem->reusable = false;
1153fe517fc9Smrg	bo_gem->use_48b_address_range = false;
115422944501Smrg
1155424e9256Smrg	memclear(get_tiling);
115622944501Smrg	get_tiling.handle = bo_gem->gem_handle;
11576d98c517Smrg	ret = drmIoctl(bufmgr_gem->fd,
11586d98c517Smrg		       DRM_IOCTL_I915_GEM_GET_TILING,
11596d98c517Smrg		       &get_tiling);
116022944501Smrg	if (ret != 0) {
116122944501Smrg		drm_intel_gem_bo_unreference(&bo_gem->bo);
1162a884aba1Smrg		pthread_mutex_unlock(&bufmgr_gem->lock);
116322944501Smrg		return NULL;
116422944501Smrg	}
116522944501Smrg	bo_gem->tiling_mode = get_tiling.tiling_mode;
116622944501Smrg	bo_gem->swizzle_mode = get_tiling.swizzle_mode;
11676d98c517Smrg	/* XXX stride is unknown */
1168fe517fc9Smrg	drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, 0);
116922944501Smrg
117020131375Smrg	DRMINITLISTHEAD(&bo_gem->vma_list);
117120131375Smrg	DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named);
1172a884aba1Smrg	pthread_mutex_unlock(&bufmgr_gem->lock);
117322944501Smrg	DBG("bo_create_from_handle: %d (%s)\n", handle, bo_gem->name);
117422944501Smrg
117522944501Smrg	return &bo_gem->bo;
117622944501Smrg}
117722944501Smrg
117822944501Smrgstatic void
117922944501Smrgdrm_intel_gem_bo_free(drm_intel_bo *bo)
118022944501Smrg{
118122944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
118222944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
118322944501Smrg	struct drm_gem_close close;
118422944501Smrg	int ret;
118522944501Smrg
118620131375Smrg	DRMLISTDEL(&bo_gem->vma_list);
118720131375Smrg	if (bo_gem->mem_virtual) {
118820131375Smrg		VG(VALGRIND_FREELIKE_BLOCK(bo_gem->mem_virtual, 0));
1189a884aba1Smrg		drm_munmap(bo_gem->mem_virtual, bo_gem->bo.size);
119020131375Smrg		bufmgr_gem->vma_count--;
119120131375Smrg	}
119220131375Smrg	if (bo_gem->gtt_virtual) {
1193a884aba1Smrg		drm_munmap(bo_gem->gtt_virtual, bo_gem->bo.size);
119420131375Smrg		bufmgr_gem->vma_count--;
119520131375Smrg	}
119622944501Smrg
119722944501Smrg	/* Close this object */
1198424e9256Smrg	memclear(close);
119922944501Smrg	close.handle = bo_gem->gem_handle;
12006d98c517Smrg	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &close);
120122944501Smrg	if (ret != 0) {
12029ce4edccSmrg		DBG("DRM_IOCTL_GEM_CLOSE %d failed (%s): %s\n",
12039ce4edccSmrg		    bo_gem->gem_handle, bo_gem->name, strerror(errno));
120422944501Smrg	}
120522944501Smrg	free(bo);
120622944501Smrg}
120722944501Smrg
120820131375Smrgstatic void
120920131375Smrgdrm_intel_gem_bo_mark_mmaps_incoherent(drm_intel_bo *bo)
121020131375Smrg{
121120131375Smrg#if HAVE_VALGRIND
121220131375Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
121320131375Smrg
121420131375Smrg	if (bo_gem->mem_virtual)
121520131375Smrg		VALGRIND_MAKE_MEM_NOACCESS(bo_gem->mem_virtual, bo->size);
121620131375Smrg
121720131375Smrg	if (bo_gem->gtt_virtual)
121820131375Smrg		VALGRIND_MAKE_MEM_NOACCESS(bo_gem->gtt_virtual, bo->size);
121920131375Smrg#endif
122020131375Smrg}
122120131375Smrg
122222944501Smrg/** Frees all cached buffers significantly older than @time. */
122322944501Smrgstatic void
122422944501Smrgdrm_intel_gem_cleanup_bo_cache(drm_intel_bufmgr_gem *bufmgr_gem, time_t time)
122522944501Smrg{
122622944501Smrg	int i;
122722944501Smrg
12286d98c517Smrg	if (bufmgr_gem->time == time)
12296d98c517Smrg		return;
12306d98c517Smrg
1231aaba2545Smrg	for (i = 0; i < bufmgr_gem->num_buckets; i++) {
123222944501Smrg		struct drm_intel_gem_bo_bucket *bucket =
123322944501Smrg		    &bufmgr_gem->cache_bucket[i];
123422944501Smrg
123522944501Smrg		while (!DRMLISTEMPTY(&bucket->head)) {
123622944501Smrg			drm_intel_bo_gem *bo_gem;
123722944501Smrg
123822944501Smrg			bo_gem = DRMLISTENTRY(drm_intel_bo_gem,
123922944501Smrg					      bucket->head.next, head);
124022944501Smrg			if (time - bo_gem->free_time <= 1)
124122944501Smrg				break;
124222944501Smrg
124322944501Smrg			DRMLISTDEL(&bo_gem->head);
124422944501Smrg
124522944501Smrg			drm_intel_gem_bo_free(&bo_gem->bo);
124622944501Smrg		}
124722944501Smrg	}
12486d98c517Smrg
12496d98c517Smrg	bufmgr_gem->time = time;
125022944501Smrg}
125122944501Smrg
125220131375Smrgstatic void drm_intel_gem_bo_purge_vma_cache(drm_intel_bufmgr_gem *bufmgr_gem)
125320131375Smrg{
125420131375Smrg	int limit;
125520131375Smrg
125620131375Smrg	DBG("%s: cached=%d, open=%d, limit=%d\n", __FUNCTION__,
125720131375Smrg	    bufmgr_gem->vma_count, bufmgr_gem->vma_open, bufmgr_gem->vma_max);
125820131375Smrg
125920131375Smrg	if (bufmgr_gem->vma_max < 0)
126020131375Smrg		return;
126120131375Smrg
126220131375Smrg	/* We may need to evict a few entries in order to create new mmaps */
126320131375Smrg	limit = bufmgr_gem->vma_max - 2*bufmgr_gem->vma_open;
126420131375Smrg	if (limit < 0)
126520131375Smrg		limit = 0;
126620131375Smrg
126720131375Smrg	while (bufmgr_gem->vma_count > limit) {
126820131375Smrg		drm_intel_bo_gem *bo_gem;
126920131375Smrg
127020131375Smrg		bo_gem = DRMLISTENTRY(drm_intel_bo_gem,
127120131375Smrg				      bufmgr_gem->vma_cache.next,
127220131375Smrg				      vma_list);
127320131375Smrg		assert(bo_gem->map_count == 0);
127420131375Smrg		DRMLISTDELINIT(&bo_gem->vma_list);
127520131375Smrg
127620131375Smrg		if (bo_gem->mem_virtual) {
1277a884aba1Smrg			drm_munmap(bo_gem->mem_virtual, bo_gem->bo.size);
127820131375Smrg			bo_gem->mem_virtual = NULL;
127920131375Smrg			bufmgr_gem->vma_count--;
128020131375Smrg		}
128120131375Smrg		if (bo_gem->gtt_virtual) {
1282a884aba1Smrg			drm_munmap(bo_gem->gtt_virtual, bo_gem->bo.size);
128320131375Smrg			bo_gem->gtt_virtual = NULL;
128420131375Smrg			bufmgr_gem->vma_count--;
128520131375Smrg		}
128620131375Smrg	}
128720131375Smrg}
128820131375Smrg
128920131375Smrgstatic void drm_intel_gem_bo_close_vma(drm_intel_bufmgr_gem *bufmgr_gem,
129020131375Smrg				       drm_intel_bo_gem *bo_gem)
129120131375Smrg{
129220131375Smrg	bufmgr_gem->vma_open--;
129320131375Smrg	DRMLISTADDTAIL(&bo_gem->vma_list, &bufmgr_gem->vma_cache);
129420131375Smrg	if (bo_gem->mem_virtual)
129520131375Smrg		bufmgr_gem->vma_count++;
129620131375Smrg	if (bo_gem->gtt_virtual)
129720131375Smrg		bufmgr_gem->vma_count++;
129820131375Smrg	drm_intel_gem_bo_purge_vma_cache(bufmgr_gem);
129920131375Smrg}
130020131375Smrg
130120131375Smrgstatic void drm_intel_gem_bo_open_vma(drm_intel_bufmgr_gem *bufmgr_gem,
130220131375Smrg				      drm_intel_bo_gem *bo_gem)
130320131375Smrg{
130420131375Smrg	bufmgr_gem->vma_open++;
130520131375Smrg	DRMLISTDEL(&bo_gem->vma_list);
130620131375Smrg	if (bo_gem->mem_virtual)
130720131375Smrg		bufmgr_gem->vma_count--;
130820131375Smrg	if (bo_gem->gtt_virtual)
130920131375Smrg		bufmgr_gem->vma_count--;
131020131375Smrg	drm_intel_gem_bo_purge_vma_cache(bufmgr_gem);
131120131375Smrg}
131220131375Smrg
131322944501Smrgstatic void
131422944501Smrgdrm_intel_gem_bo_unreference_final(drm_intel_bo *bo, time_t time)
131522944501Smrg{
131622944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
131722944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
131822944501Smrg	struct drm_intel_gem_bo_bucket *bucket;
131922944501Smrg	int i;
132022944501Smrg
132122944501Smrg	/* Unreference all the target buffers */
132222944501Smrg	for (i = 0; i < bo_gem->reloc_count; i++) {
1323aaba2545Smrg		if (bo_gem->reloc_target_info[i].bo != bo) {
1324aaba2545Smrg			drm_intel_gem_bo_unreference_locked_timed(bo_gem->
1325aaba2545Smrg								  reloc_target_info[i].bo,
1326aaba2545Smrg								  time);
1327aaba2545Smrg		}
132822944501Smrg	}
1329fe517fc9Smrg	for (i = 0; i < bo_gem->softpin_target_count; i++)
1330fe517fc9Smrg		drm_intel_gem_bo_unreference_locked_timed(bo_gem->softpin_target[i],
1331fe517fc9Smrg								  time);
133222944501Smrg	bo_gem->reloc_count = 0;
133320131375Smrg	bo_gem->used_as_reloc_target = false;
1334fe517fc9Smrg	bo_gem->softpin_target_count = 0;
133522944501Smrg
133622944501Smrg	DBG("bo_unreference final: %d (%s)\n",
133722944501Smrg	    bo_gem->gem_handle, bo_gem->name);
133822944501Smrg
133922944501Smrg	/* release memory associated with this object */
134022944501Smrg	if (bo_gem->reloc_target_info) {
134122944501Smrg		free(bo_gem->reloc_target_info);
134222944501Smrg		bo_gem->reloc_target_info = NULL;
134322944501Smrg	}
134422944501Smrg	if (bo_gem->relocs) {
134522944501Smrg		free(bo_gem->relocs);
134622944501Smrg		bo_gem->relocs = NULL;
134722944501Smrg	}
1348fe517fc9Smrg	if (bo_gem->softpin_target) {
1349fe517fc9Smrg		free(bo_gem->softpin_target);
1350fe517fc9Smrg		bo_gem->softpin_target = NULL;
1351fe517fc9Smrg		bo_gem->softpin_target_size = 0;
1352fe517fc9Smrg	}
135322944501Smrg
135420131375Smrg	/* Clear any left-over mappings */
135520131375Smrg	if (bo_gem->map_count) {
135620131375Smrg		DBG("bo freed with non-zero map-count %d\n", bo_gem->map_count);
135720131375Smrg		bo_gem->map_count = 0;
135820131375Smrg		drm_intel_gem_bo_close_vma(bufmgr_gem, bo_gem);
135920131375Smrg		drm_intel_gem_bo_mark_mmaps_incoherent(bo);
136020131375Smrg	}
136120131375Smrg
136220131375Smrg	DRMLISTDEL(&bo_gem->name_list);
136320131375Smrg
136422944501Smrg	bucket = drm_intel_gem_bo_bucket_for_size(bufmgr_gem, bo->size);
136522944501Smrg	/* Put the buffer into our internal cache for reuse if we can. */
136622944501Smrg	if (bufmgr_gem->bo_reuse && bo_gem->reusable && bucket != NULL &&
136722944501Smrg	    drm_intel_gem_bo_madvise_internal(bufmgr_gem, bo_gem,
136822944501Smrg					      I915_MADV_DONTNEED)) {
136922944501Smrg		bo_gem->free_time = time;
137022944501Smrg
137122944501Smrg		bo_gem->name = NULL;
137222944501Smrg		bo_gem->validate_index = -1;
137322944501Smrg
137422944501Smrg		DRMLISTADDTAIL(&bo_gem->head, &bucket->head);
137522944501Smrg	} else {
137622944501Smrg		drm_intel_gem_bo_free(bo);
137722944501Smrg	}
137822944501Smrg}
137922944501Smrg
138022944501Smrgstatic void drm_intel_gem_bo_unreference_locked_timed(drm_intel_bo *bo,
138122944501Smrg						      time_t time)
138222944501Smrg{
138322944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
138422944501Smrg
138522944501Smrg	assert(atomic_read(&bo_gem->refcount) > 0);
138622944501Smrg	if (atomic_dec_and_test(&bo_gem->refcount))
138722944501Smrg		drm_intel_gem_bo_unreference_final(bo, time);
138822944501Smrg}
138922944501Smrg
139022944501Smrgstatic void drm_intel_gem_bo_unreference(drm_intel_bo *bo)
139122944501Smrg{
139222944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
139322944501Smrg
139422944501Smrg	assert(atomic_read(&bo_gem->refcount) > 0);
1395a884aba1Smrg
1396a884aba1Smrg	if (atomic_add_unless(&bo_gem->refcount, -1, 1)) {
139722944501Smrg		drm_intel_bufmgr_gem *bufmgr_gem =
139822944501Smrg		    (drm_intel_bufmgr_gem *) bo->bufmgr;
139922944501Smrg		struct timespec time;
140022944501Smrg
140122944501Smrg		clock_gettime(CLOCK_MONOTONIC, &time);
140222944501Smrg
140322944501Smrg		pthread_mutex_lock(&bufmgr_gem->lock);
1404a884aba1Smrg
1405a884aba1Smrg		if (atomic_dec_and_test(&bo_gem->refcount)) {
1406a884aba1Smrg			drm_intel_gem_bo_unreference_final(bo, time.tv_sec);
1407a884aba1Smrg			drm_intel_gem_cleanup_bo_cache(bufmgr_gem, time.tv_sec);
1408a884aba1Smrg		}
1409a884aba1Smrg
141022944501Smrg		pthread_mutex_unlock(&bufmgr_gem->lock);
141122944501Smrg	}
141222944501Smrg}
141322944501Smrg
141422944501Smrgstatic int drm_intel_gem_bo_map(drm_intel_bo *bo, int write_enable)
141522944501Smrg{
141622944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
141722944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
141822944501Smrg	struct drm_i915_gem_set_domain set_domain;
141922944501Smrg	int ret;
142022944501Smrg
1421a884aba1Smrg	if (bo_gem->is_userptr) {
1422a884aba1Smrg		/* Return the same user ptr */
1423a884aba1Smrg		bo->virtual = bo_gem->user_virtual;
1424a884aba1Smrg		return 0;
1425a884aba1Smrg	}
1426a884aba1Smrg
142722944501Smrg	pthread_mutex_lock(&bufmgr_gem->lock);
142822944501Smrg
142920131375Smrg	if (bo_gem->map_count++ == 0)
143020131375Smrg		drm_intel_gem_bo_open_vma(bufmgr_gem, bo_gem);
143120131375Smrg
143222944501Smrg	if (!bo_gem->mem_virtual) {
143322944501Smrg		struct drm_i915_gem_mmap mmap_arg;
143422944501Smrg
143520131375Smrg		DBG("bo_map: %d (%s), map_count=%d\n",
143620131375Smrg		    bo_gem->gem_handle, bo_gem->name, bo_gem->map_count);
143722944501Smrg
1438424e9256Smrg		memclear(mmap_arg);
143922944501Smrg		mmap_arg.handle = bo_gem->gem_handle;
144022944501Smrg		mmap_arg.size = bo->size;
14416d98c517Smrg		ret = drmIoctl(bufmgr_gem->fd,
14426d98c517Smrg			       DRM_IOCTL_I915_GEM_MMAP,
14436d98c517Smrg			       &mmap_arg);
144422944501Smrg		if (ret != 0) {
144522944501Smrg			ret = -errno;
14469ce4edccSmrg			DBG("%s:%d: Error mapping buffer %d (%s): %s .\n",
14479ce4edccSmrg			    __FILE__, __LINE__, bo_gem->gem_handle,
14489ce4edccSmrg			    bo_gem->name, strerror(errno));
144920131375Smrg			if (--bo_gem->map_count == 0)
145020131375Smrg				drm_intel_gem_bo_close_vma(bufmgr_gem, bo_gem);
145122944501Smrg			pthread_mutex_unlock(&bufmgr_gem->lock);
145222944501Smrg			return ret;
145322944501Smrg		}
145420131375Smrg		VG(VALGRIND_MALLOCLIKE_BLOCK(mmap_arg.addr_ptr, mmap_arg.size, 0, 1));
145522944501Smrg		bo_gem->mem_virtual = (void *)(uintptr_t) mmap_arg.addr_ptr;
145622944501Smrg	}
145722944501Smrg	DBG("bo_map: %d (%s) -> %p\n", bo_gem->gem_handle, bo_gem->name,
145822944501Smrg	    bo_gem->mem_virtual);
145922944501Smrg	bo->virtual = bo_gem->mem_virtual;
146022944501Smrg
1461424e9256Smrg	memclear(set_domain);
146222944501Smrg	set_domain.handle = bo_gem->gem_handle;
146322944501Smrg	set_domain.read_domains = I915_GEM_DOMAIN_CPU;
146422944501Smrg	if (write_enable)
146522944501Smrg		set_domain.write_domain = I915_GEM_DOMAIN_CPU;
146622944501Smrg	else
146722944501Smrg		set_domain.write_domain = 0;
14686d98c517Smrg	ret = drmIoctl(bufmgr_gem->fd,
14696d98c517Smrg		       DRM_IOCTL_I915_GEM_SET_DOMAIN,
14706d98c517Smrg		       &set_domain);
147122944501Smrg	if (ret != 0) {
14729ce4edccSmrg		DBG("%s:%d: Error setting to CPU domain %d: %s\n",
14739ce4edccSmrg		    __FILE__, __LINE__, bo_gem->gem_handle,
14749ce4edccSmrg		    strerror(errno));
147522944501Smrg	}
147622944501Smrg
147720131375Smrg	if (write_enable)
147820131375Smrg		bo_gem->mapped_cpu_write = true;
147920131375Smrg
148020131375Smrg	drm_intel_gem_bo_mark_mmaps_incoherent(bo);
148120131375Smrg	VG(VALGRIND_MAKE_MEM_DEFINED(bo_gem->mem_virtual, bo->size));
148222944501Smrg	pthread_mutex_unlock(&bufmgr_gem->lock);
148322944501Smrg
148422944501Smrg	return 0;
148522944501Smrg}
148622944501Smrg
148720131375Smrgstatic int
148820131375Smrgmap_gtt(drm_intel_bo *bo)
148922944501Smrg{
149022944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
149122944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
149222944501Smrg	int ret;
149322944501Smrg
1494a884aba1Smrg	if (bo_gem->is_userptr)
1495a884aba1Smrg		return -EINVAL;
1496a884aba1Smrg
149720131375Smrg	if (bo_gem->map_count++ == 0)
149820131375Smrg		drm_intel_gem_bo_open_vma(bufmgr_gem, bo_gem);
149922944501Smrg
150022944501Smrg	/* Get a mapping of the buffer if we haven't before. */
150122944501Smrg	if (bo_gem->gtt_virtual == NULL) {
150222944501Smrg		struct drm_i915_gem_mmap_gtt mmap_arg;
150322944501Smrg
150420131375Smrg		DBG("bo_map_gtt: mmap %d (%s), map_count=%d\n",
150520131375Smrg		    bo_gem->gem_handle, bo_gem->name, bo_gem->map_count);
150622944501Smrg
1507424e9256Smrg		memclear(mmap_arg);
150822944501Smrg		mmap_arg.handle = bo_gem->gem_handle;
150922944501Smrg
151022944501Smrg		/* Get the fake offset back... */
15116d98c517Smrg		ret = drmIoctl(bufmgr_gem->fd,
15126d98c517Smrg			       DRM_IOCTL_I915_GEM_MMAP_GTT,
15136d98c517Smrg			       &mmap_arg);
151422944501Smrg		if (ret != 0) {
151522944501Smrg			ret = -errno;
15169ce4edccSmrg			DBG("%s:%d: Error preparing buffer map %d (%s): %s .\n",
15179ce4edccSmrg			    __FILE__, __LINE__,
15189ce4edccSmrg			    bo_gem->gem_handle, bo_gem->name,
15199ce4edccSmrg			    strerror(errno));
152020131375Smrg			if (--bo_gem->map_count == 0)
152120131375Smrg				drm_intel_gem_bo_close_vma(bufmgr_gem, bo_gem);
152222944501Smrg			return ret;
152322944501Smrg		}
152422944501Smrg
152522944501Smrg		/* and mmap it */
1526aec75c42Sriastradh		ret = drmMap(bufmgr_gem->fd, mmap_arg.offset, bo->size,
1527aec75c42Sriastradh		    &bo_gem->gtt_virtual);
1528aec75c42Sriastradh		if (ret) {
152922944501Smrg			bo_gem->gtt_virtual = NULL;
15309ce4edccSmrg			DBG("%s:%d: Error mapping buffer %d (%s): %s .\n",
15319ce4edccSmrg			    __FILE__, __LINE__,
15329ce4edccSmrg			    bo_gem->gem_handle, bo_gem->name,
15339ce4edccSmrg			    strerror(errno));
153420131375Smrg			if (--bo_gem->map_count == 0)
153520131375Smrg				drm_intel_gem_bo_close_vma(bufmgr_gem, bo_gem);
153622944501Smrg			return ret;
153722944501Smrg		}
153822944501Smrg	}
153922944501Smrg
154022944501Smrg	bo->virtual = bo_gem->gtt_virtual;
154122944501Smrg
154222944501Smrg	DBG("bo_map_gtt: %d (%s) -> %p\n", bo_gem->gem_handle, bo_gem->name,
154322944501Smrg	    bo_gem->gtt_virtual);
154422944501Smrg
154520131375Smrg	return 0;
154620131375Smrg}
154720131375Smrg
1548424e9256Smrgint
1549a884aba1Smrgdrm_intel_gem_bo_map_gtt(drm_intel_bo *bo)
155020131375Smrg{
155120131375Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
155220131375Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
155320131375Smrg	struct drm_i915_gem_set_domain set_domain;
155420131375Smrg	int ret;
155520131375Smrg
155620131375Smrg	pthread_mutex_lock(&bufmgr_gem->lock);
155720131375Smrg
155820131375Smrg	ret = map_gtt(bo);
155920131375Smrg	if (ret) {
156020131375Smrg		pthread_mutex_unlock(&bufmgr_gem->lock);
156120131375Smrg		return ret;
156220131375Smrg	}
156320131375Smrg
156420131375Smrg	/* Now move it to the GTT domain so that the GPU and CPU
156520131375Smrg	 * caches are flushed and the GPU isn't actively using the
156620131375Smrg	 * buffer.
156720131375Smrg	 *
156820131375Smrg	 * The pagefault handler does this domain change for us when
156920131375Smrg	 * it has unbound the BO from the GTT, but it's up to us to
157020131375Smrg	 * tell it when we're about to use things if we had done
157120131375Smrg	 * rendering and it still happens to be bound to the GTT.
157220131375Smrg	 */
1573424e9256Smrg	memclear(set_domain);
157422944501Smrg	set_domain.handle = bo_gem->gem_handle;
157522944501Smrg	set_domain.read_domains = I915_GEM_DOMAIN_GTT;
157622944501Smrg	set_domain.write_domain = I915_GEM_DOMAIN_GTT;
15776d98c517Smrg	ret = drmIoctl(bufmgr_gem->fd,
15786d98c517Smrg		       DRM_IOCTL_I915_GEM_SET_DOMAIN,
15796d98c517Smrg		       &set_domain);
158022944501Smrg	if (ret != 0) {
15819ce4edccSmrg		DBG("%s:%d: Error setting domain %d: %s\n",
15829ce4edccSmrg		    __FILE__, __LINE__, bo_gem->gem_handle,
15839ce4edccSmrg		    strerror(errno));
158422944501Smrg	}
158522944501Smrg
158620131375Smrg	drm_intel_gem_bo_mark_mmaps_incoherent(bo);
158720131375Smrg	VG(VALGRIND_MAKE_MEM_DEFINED(bo_gem->gtt_virtual, bo->size));
158822944501Smrg	pthread_mutex_unlock(&bufmgr_gem->lock);
158922944501Smrg
15906d98c517Smrg	return 0;
159122944501Smrg}
159222944501Smrg
159320131375Smrg/**
159420131375Smrg * Performs a mapping of the buffer object like the normal GTT
159520131375Smrg * mapping, but avoids waiting for the GPU to be done reading from or
159620131375Smrg * rendering to the buffer.
159720131375Smrg *
159820131375Smrg * This is used in the implementation of GL_ARB_map_buffer_range: The
159920131375Smrg * user asks to create a buffer, then does a mapping, fills some
160020131375Smrg * space, runs a drawing command, then asks to map it again without
160120131375Smrg * synchronizing because it guarantees that it won't write over the
160220131375Smrg * data that the GPU is busy using (or, more specifically, that if it
160320131375Smrg * does write over the data, it acknowledges that rendering is
160420131375Smrg * undefined).
160520131375Smrg */
160620131375Smrg
1607424e9256Smrgint
1608a884aba1Smrgdrm_intel_gem_bo_map_unsynchronized(drm_intel_bo *bo)
160922944501Smrg{
161022944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
161120131375Smrg#ifdef HAVE_VALGRIND
161220131375Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
161320131375Smrg#endif
161420131375Smrg	int ret;
161522944501Smrg
161620131375Smrg	/* If the CPU cache isn't coherent with the GTT, then use a
161720131375Smrg	 * regular synchronized mapping.  The problem is that we don't
161820131375Smrg	 * track where the buffer was last used on the CPU side in
161920131375Smrg	 * terms of drm_intel_bo_map vs drm_intel_gem_bo_map_gtt, so
162020131375Smrg	 * we would potentially corrupt the buffer even when the user
162120131375Smrg	 * does reasonable things.
162220131375Smrg	 */
162320131375Smrg	if (!bufmgr_gem->has_llc)
162420131375Smrg		return drm_intel_gem_bo_map_gtt(bo);
162522944501Smrg
162622944501Smrg	pthread_mutex_lock(&bufmgr_gem->lock);
162720131375Smrg
162820131375Smrg	ret = map_gtt(bo);
162920131375Smrg	if (ret == 0) {
163020131375Smrg		drm_intel_gem_bo_mark_mmaps_incoherent(bo);
163120131375Smrg		VG(VALGRIND_MAKE_MEM_DEFINED(bo_gem->gtt_virtual, bo->size));
163220131375Smrg	}
163320131375Smrg
163422944501Smrg	pthread_mutex_unlock(&bufmgr_gem->lock);
163522944501Smrg
163622944501Smrg	return ret;
163722944501Smrg}
163822944501Smrg
163922944501Smrgstatic int drm_intel_gem_bo_unmap(drm_intel_bo *bo)
164022944501Smrg{
1641a884aba1Smrg	drm_intel_bufmgr_gem *bufmgr_gem;
164222944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
164320131375Smrg	int ret = 0;
164422944501Smrg
164522944501Smrg	if (bo == NULL)
164622944501Smrg		return 0;
164722944501Smrg
1648a884aba1Smrg	if (bo_gem->is_userptr)
1649a884aba1Smrg		return 0;
1650a884aba1Smrg
1651a884aba1Smrg	bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
1652a884aba1Smrg
165322944501Smrg	pthread_mutex_lock(&bufmgr_gem->lock);
165422944501Smrg
165520131375Smrg	if (bo_gem->map_count <= 0) {
165620131375Smrg		DBG("attempted to unmap an unmapped bo\n");
165720131375Smrg		pthread_mutex_unlock(&bufmgr_gem->lock);
165820131375Smrg		/* Preserve the old behaviour of just treating this as a
165920131375Smrg		 * no-op rather than reporting the error.
166020131375Smrg		 */
166120131375Smrg		return 0;
166220131375Smrg	}
166320131375Smrg
166420131375Smrg	if (bo_gem->mapped_cpu_write) {
166520131375Smrg		struct drm_i915_gem_sw_finish sw_finish;
166620131375Smrg
166720131375Smrg		/* Cause a flush to happen if the buffer's pinned for
166820131375Smrg		 * scanout, so the results show up in a timely manner.
166920131375Smrg		 * Unlike GTT set domains, this only does work if the
167020131375Smrg		 * buffer should be scanout-related.
167120131375Smrg		 */
1672424e9256Smrg		memclear(sw_finish);
167320131375Smrg		sw_finish.handle = bo_gem->gem_handle;
167420131375Smrg		ret = drmIoctl(bufmgr_gem->fd,
167520131375Smrg			       DRM_IOCTL_I915_GEM_SW_FINISH,
167620131375Smrg			       &sw_finish);
167720131375Smrg		ret = ret == -1 ? -errno : 0;
167820131375Smrg
167920131375Smrg		bo_gem->mapped_cpu_write = false;
168020131375Smrg	}
168122944501Smrg
168220131375Smrg	/* We need to unmap after every innovation as we cannot track
168320131375Smrg	 * an open vma for every bo as that will exhaasut the system
168420131375Smrg	 * limits and cause later failures.
168520131375Smrg	 */
168620131375Smrg	if (--bo_gem->map_count == 0) {
168720131375Smrg		drm_intel_gem_bo_close_vma(bufmgr_gem, bo_gem);
168820131375Smrg		drm_intel_gem_bo_mark_mmaps_incoherent(bo);
168920131375Smrg		bo->virtual = NULL;
169020131375Smrg	}
169122944501Smrg	pthread_mutex_unlock(&bufmgr_gem->lock);
169222944501Smrg
169322944501Smrg	return ret;
169422944501Smrg}
169522944501Smrg
1696424e9256Smrgint
1697a884aba1Smrgdrm_intel_gem_bo_unmap_gtt(drm_intel_bo *bo)
169820131375Smrg{
169920131375Smrg	return drm_intel_gem_bo_unmap(bo);
170020131375Smrg}
170120131375Smrg
170222944501Smrgstatic int
170322944501Smrgdrm_intel_gem_bo_subdata(drm_intel_bo *bo, unsigned long offset,
170422944501Smrg			 unsigned long size, const void *data)
170522944501Smrg{
170622944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
170722944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
170822944501Smrg	struct drm_i915_gem_pwrite pwrite;
170922944501Smrg	int ret;
171022944501Smrg
1711a884aba1Smrg	if (bo_gem->is_userptr)
1712a884aba1Smrg		return -EINVAL;
1713a884aba1Smrg
1714424e9256Smrg	memclear(pwrite);
171522944501Smrg	pwrite.handle = bo_gem->gem_handle;
171622944501Smrg	pwrite.offset = offset;
171722944501Smrg	pwrite.size = size;
171822944501Smrg	pwrite.data_ptr = (uint64_t) (uintptr_t) data;
17196d98c517Smrg	ret = drmIoctl(bufmgr_gem->fd,
17206d98c517Smrg		       DRM_IOCTL_I915_GEM_PWRITE,
17216d98c517Smrg		       &pwrite);
172222944501Smrg	if (ret != 0) {
172322944501Smrg		ret = -errno;
17249ce4edccSmrg		DBG("%s:%d: Error writing data to buffer %d: (%d %d) %s .\n",
17259ce4edccSmrg		    __FILE__, __LINE__, bo_gem->gem_handle, (int)offset,
17269ce4edccSmrg		    (int)size, strerror(errno));
172722944501Smrg	}
172822944501Smrg
172922944501Smrg	return ret;
173022944501Smrg}
173122944501Smrg
173222944501Smrgstatic int
173322944501Smrgdrm_intel_gem_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, int crtc_id)
173422944501Smrg{
173522944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
173622944501Smrg	struct drm_i915_get_pipe_from_crtc_id get_pipe_from_crtc_id;
173722944501Smrg	int ret;
173822944501Smrg
1739424e9256Smrg	memclear(get_pipe_from_crtc_id);
174022944501Smrg	get_pipe_from_crtc_id.crtc_id = crtc_id;
17416d98c517Smrg	ret = drmIoctl(bufmgr_gem->fd,
17426d98c517Smrg		       DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID,
17436d98c517Smrg		       &get_pipe_from_crtc_id);
174422944501Smrg	if (ret != 0) {
174522944501Smrg		/* We return -1 here to signal that we don't
174622944501Smrg		 * know which pipe is associated with this crtc.
174722944501Smrg		 * This lets the caller know that this information
174822944501Smrg		 * isn't available; using the wrong pipe for
174922944501Smrg		 * vblank waiting can cause the chipset to lock up
175022944501Smrg		 */
175122944501Smrg		return -1;
175222944501Smrg	}
175322944501Smrg
175422944501Smrg	return get_pipe_from_crtc_id.pipe;
175522944501Smrg}
175622944501Smrg
175722944501Smrgstatic int
175822944501Smrgdrm_intel_gem_bo_get_subdata(drm_intel_bo *bo, unsigned long offset,
175922944501Smrg			     unsigned long size, void *data)
176022944501Smrg{
176122944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
176222944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
176322944501Smrg	struct drm_i915_gem_pread pread;
176422944501Smrg	int ret;
176522944501Smrg
1766a884aba1Smrg	if (bo_gem->is_userptr)
1767a884aba1Smrg		return -EINVAL;
1768a884aba1Smrg
1769424e9256Smrg	memclear(pread);
177022944501Smrg	pread.handle = bo_gem->gem_handle;
177122944501Smrg	pread.offset = offset;
177222944501Smrg	pread.size = size;
177322944501Smrg	pread.data_ptr = (uint64_t) (uintptr_t) data;
17746d98c517Smrg	ret = drmIoctl(bufmgr_gem->fd,
17756d98c517Smrg		       DRM_IOCTL_I915_GEM_PREAD,
17766d98c517Smrg		       &pread);
177722944501Smrg	if (ret != 0) {
177822944501Smrg		ret = -errno;
17799ce4edccSmrg		DBG("%s:%d: Error reading data from buffer %d: (%d %d) %s .\n",
17809ce4edccSmrg		    __FILE__, __LINE__, bo_gem->gem_handle, (int)offset,
17819ce4edccSmrg		    (int)size, strerror(errno));
178222944501Smrg	}
178322944501Smrg
178422944501Smrg	return ret;
178522944501Smrg}
178622944501Smrg
17879ce4edccSmrg/** Waits for all GPU rendering with the object to have completed. */
178822944501Smrgstatic void
178922944501Smrgdrm_intel_gem_bo_wait_rendering(drm_intel_bo *bo)
179022944501Smrg{
17919ce4edccSmrg	drm_intel_gem_bo_start_gtt_access(bo, 1);
179222944501Smrg}
179322944501Smrg
179420131375Smrg/**
179520131375Smrg * Waits on a BO for the given amount of time.
179620131375Smrg *
179720131375Smrg * @bo: buffer object to wait for
179820131375Smrg * @timeout_ns: amount of time to wait in nanoseconds.
179920131375Smrg *   If value is less than 0, an infinite wait will occur.
180020131375Smrg *
180120131375Smrg * Returns 0 if the wait was successful ie. the last batch referencing the
180220131375Smrg * object has completed within the allotted time. Otherwise some negative return
180320131375Smrg * value describes the error. Of particular interest is -ETIME when the wait has
180420131375Smrg * failed to yield the desired result.
180520131375Smrg *
180620131375Smrg * Similar to drm_intel_gem_bo_wait_rendering except a timeout parameter allows
180720131375Smrg * the operation to give up after a certain amount of time. Another subtle
180820131375Smrg * difference is the internal locking semantics are different (this variant does
180920131375Smrg * not hold the lock for the duration of the wait). This makes the wait subject
181020131375Smrg * to a larger userspace race window.
181120131375Smrg *
181220131375Smrg * The implementation shall wait until the object is no longer actively
181320131375Smrg * referenced within a batch buffer at the time of the call. The wait will
181420131375Smrg * not guarantee that the buffer is re-issued via another thread, or an flinked
181520131375Smrg * handle. Userspace must make sure this race does not occur if such precision
181620131375Smrg * is important.
1817424e9256Smrg *
1818424e9256Smrg * Note that some kernels have broken the inifite wait for negative values
1819424e9256Smrg * promise, upgrade to latest stable kernels if this is the case.
182020131375Smrg */
1821424e9256Smrgint
1822a884aba1Smrgdrm_intel_gem_bo_wait(drm_intel_bo *bo, int64_t timeout_ns)
182320131375Smrg{
182420131375Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
182520131375Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
182620131375Smrg	struct drm_i915_gem_wait wait;
182720131375Smrg	int ret;
182820131375Smrg
182920131375Smrg	if (!bufmgr_gem->has_wait_timeout) {
183020131375Smrg		DBG("%s:%d: Timed wait is not supported. Falling back to "
183120131375Smrg		    "infinite wait\n", __FILE__, __LINE__);
183220131375Smrg		if (timeout_ns) {
183320131375Smrg			drm_intel_gem_bo_wait_rendering(bo);
183420131375Smrg			return 0;
183520131375Smrg		} else {
183620131375Smrg			return drm_intel_gem_bo_busy(bo) ? -ETIME : 0;
183720131375Smrg		}
183820131375Smrg	}
183920131375Smrg
1840424e9256Smrg	memclear(wait);
184120131375Smrg	wait.bo_handle = bo_gem->gem_handle;
184220131375Smrg	wait.timeout_ns = timeout_ns;
184320131375Smrg	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_WAIT, &wait);
184420131375Smrg	if (ret == -1)
184520131375Smrg		return -errno;
184620131375Smrg
184720131375Smrg	return ret;
184820131375Smrg}
184920131375Smrg
185022944501Smrg/**
185122944501Smrg * Sets the object to the GTT read and possibly write domain, used by the X
185222944501Smrg * 2D driver in the absence of kernel support to do drm_intel_gem_bo_map_gtt().
185322944501Smrg *
185422944501Smrg * In combination with drm_intel_gem_bo_pin() and manual fence management, we
185522944501Smrg * can do tiled pixmaps this way.
185622944501Smrg */
1857424e9256Smrgvoid
185822944501Smrgdrm_intel_gem_bo_start_gtt_access(drm_intel_bo *bo, int write_enable)
185922944501Smrg{
186022944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
186122944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
186222944501Smrg	struct drm_i915_gem_set_domain set_domain;
186322944501Smrg	int ret;
186422944501Smrg
1865424e9256Smrg	memclear(set_domain);
186622944501Smrg	set_domain.handle = bo_gem->gem_handle;
186722944501Smrg	set_domain.read_domains = I915_GEM_DOMAIN_GTT;
186822944501Smrg	set_domain.write_domain = write_enable ? I915_GEM_DOMAIN_GTT : 0;
18696d98c517Smrg	ret = drmIoctl(bufmgr_gem->fd,
18706d98c517Smrg		       DRM_IOCTL_I915_GEM_SET_DOMAIN,
18716d98c517Smrg		       &set_domain);
187222944501Smrg	if (ret != 0) {
18739ce4edccSmrg		DBG("%s:%d: Error setting memory domains %d (%08x %08x): %s .\n",
18749ce4edccSmrg		    __FILE__, __LINE__, bo_gem->gem_handle,
18759ce4edccSmrg		    set_domain.read_domains, set_domain.write_domain,
18769ce4edccSmrg		    strerror(errno));
187722944501Smrg	}
187822944501Smrg}
187922944501Smrg
188022944501Smrgstatic void
188122944501Smrgdrm_intel_bufmgr_gem_destroy(drm_intel_bufmgr *bufmgr)
188222944501Smrg{
188322944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
1884424e9256Smrg	struct drm_gem_close close_bo;
1885424e9256Smrg	int i, ret;
188622944501Smrg
188722944501Smrg	free(bufmgr_gem->exec2_objects);
188822944501Smrg	free(bufmgr_gem->exec_objects);
188922944501Smrg	free(bufmgr_gem->exec_bos);
189022944501Smrg
189122944501Smrg	pthread_mutex_destroy(&bufmgr_gem->lock);
189222944501Smrg
189322944501Smrg	/* Free any cached buffer objects we were going to reuse */
1894aaba2545Smrg	for (i = 0; i < bufmgr_gem->num_buckets; i++) {
189522944501Smrg		struct drm_intel_gem_bo_bucket *bucket =
189622944501Smrg		    &bufmgr_gem->cache_bucket[i];
189722944501Smrg		drm_intel_bo_gem *bo_gem;
189822944501Smrg
189922944501Smrg		while (!DRMLISTEMPTY(&bucket->head)) {
190022944501Smrg			bo_gem = DRMLISTENTRY(drm_intel_bo_gem,
190122944501Smrg					      bucket->head.next, head);
190222944501Smrg			DRMLISTDEL(&bo_gem->head);
190322944501Smrg
190422944501Smrg			drm_intel_gem_bo_free(&bo_gem->bo);
190522944501Smrg		}
190622944501Smrg	}
190722944501Smrg
1908424e9256Smrg	/* Release userptr bo kept hanging around for optimisation. */
1909424e9256Smrg	if (bufmgr_gem->userptr_active.ptr) {
1910424e9256Smrg		memclear(close_bo);
1911424e9256Smrg		close_bo.handle = bufmgr_gem->userptr_active.handle;
1912424e9256Smrg		ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
1913424e9256Smrg		free(bufmgr_gem->userptr_active.ptr);
1914424e9256Smrg		if (ret)
1915424e9256Smrg			fprintf(stderr,
1916424e9256Smrg				"Failed to release test userptr object! (%d) "
1917424e9256Smrg				"i915 kernel driver may not be sane!\n", errno);
1918424e9256Smrg	}
1919424e9256Smrg
192022944501Smrg	free(bufmgr);
192122944501Smrg}
192222944501Smrg
192322944501Smrg/**
192422944501Smrg * Adds the target buffer to the validation list and adds the relocation
192522944501Smrg * to the reloc_buffer's relocation list.
192622944501Smrg *
192722944501Smrg * The relocation entry at the given offset must already contain the
192822944501Smrg * precomputed relocation value, because the kernel will optimize out
192922944501Smrg * the relocation entry write when the buffer hasn't moved from the
193022944501Smrg * last known offset in target_bo.
193122944501Smrg */
193222944501Smrgstatic int
193322944501Smrgdo_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
193422944501Smrg		 drm_intel_bo *target_bo, uint32_t target_offset,
193522944501Smrg		 uint32_t read_domains, uint32_t write_domain,
193620131375Smrg		 bool need_fence)
193722944501Smrg{
193822944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
193922944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
194022944501Smrg	drm_intel_bo_gem *target_bo_gem = (drm_intel_bo_gem *) target_bo;
194120131375Smrg	bool fenced_command;
194222944501Smrg
194322944501Smrg	if (bo_gem->has_error)
194422944501Smrg		return -ENOMEM;
194522944501Smrg
194622944501Smrg	if (target_bo_gem->has_error) {
194720131375Smrg		bo_gem->has_error = true;
194822944501Smrg		return -ENOMEM;
194922944501Smrg	}
195022944501Smrg
195122944501Smrg	/* We never use HW fences for rendering on 965+ */
195222944501Smrg	if (bufmgr_gem->gen >= 4)
195320131375Smrg		need_fence = false;
195422944501Smrg
19559ce4edccSmrg	fenced_command = need_fence;
19569ce4edccSmrg	if (target_bo_gem->tiling_mode == I915_TILING_NONE)
195720131375Smrg		need_fence = false;
19589ce4edccSmrg
195922944501Smrg	/* Create a new relocation list if needed */
196022944501Smrg	if (bo_gem->relocs == NULL && drm_intel_setup_reloc_list(bo))
196122944501Smrg		return -ENOMEM;
196222944501Smrg
196322944501Smrg	/* Check overflow */
196422944501Smrg	assert(bo_gem->reloc_count < bufmgr_gem->max_relocs);
196522944501Smrg
196622944501Smrg	/* Check args */
196722944501Smrg	assert(offset <= bo->size - 4);
196822944501Smrg	assert((write_domain & (write_domain - 1)) == 0);
196922944501Smrg
19703c748557Ssnj	/* An object needing a fence is a tiled buffer, so it won't have
19713c748557Ssnj	 * relocs to other buffers.
19723c748557Ssnj	 */
19733c748557Ssnj	if (need_fence) {
19743c748557Ssnj		assert(target_bo_gem->reloc_count == 0);
19753c748557Ssnj		target_bo_gem->reloc_tree_fences = 1;
19763c748557Ssnj	}
19773c748557Ssnj
197822944501Smrg	/* Make sure that we're not adding a reloc to something whose size has
197922944501Smrg	 * already been accounted for.
198022944501Smrg	 */
198122944501Smrg	assert(!bo_gem->used_as_reloc_target);
1982aaba2545Smrg	if (target_bo_gem != bo_gem) {
198320131375Smrg		target_bo_gem->used_as_reloc_target = true;
1984aaba2545Smrg		bo_gem->reloc_tree_size += target_bo_gem->reloc_tree_size;
19853c748557Ssnj		bo_gem->reloc_tree_fences += target_bo_gem->reloc_tree_fences;
1986aaba2545Smrg	}
198722944501Smrg
198822944501Smrg	bo_gem->reloc_target_info[bo_gem->reloc_count].bo = target_bo;
1989aaba2545Smrg	if (target_bo != bo)
1990aaba2545Smrg		drm_intel_gem_bo_reference(target_bo);
19919ce4edccSmrg	if (fenced_command)
199222944501Smrg		bo_gem->reloc_target_info[bo_gem->reloc_count].flags =
199322944501Smrg			DRM_INTEL_RELOC_FENCE;
199422944501Smrg	else
199522944501Smrg		bo_gem->reloc_target_info[bo_gem->reloc_count].flags = 0;
199622944501Smrg
1997fe517fc9Smrg	bo_gem->relocs[bo_gem->reloc_count].offset = offset;
1998fe517fc9Smrg	bo_gem->relocs[bo_gem->reloc_count].delta = target_offset;
1999fe517fc9Smrg	bo_gem->relocs[bo_gem->reloc_count].target_handle =
2000fe517fc9Smrg	    target_bo_gem->gem_handle;
2001fe517fc9Smrg	bo_gem->relocs[bo_gem->reloc_count].read_domains = read_domains;
2002fe517fc9Smrg	bo_gem->relocs[bo_gem->reloc_count].write_domain = write_domain;
2003fe517fc9Smrg	bo_gem->relocs[bo_gem->reloc_count].presumed_offset = target_bo->offset64;
200422944501Smrg	bo_gem->reloc_count++;
200522944501Smrg
200622944501Smrg	return 0;
200722944501Smrg}
200822944501Smrg
2009fe517fc9Smrgstatic void
2010fe517fc9Smrgdrm_intel_gem_bo_use_48b_address_range(drm_intel_bo *bo, uint32_t enable)
2011fe517fc9Smrg{
2012fe517fc9Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
2013fe517fc9Smrg	bo_gem->use_48b_address_range = enable;
2014fe517fc9Smrg}
2015fe517fc9Smrg
2016fe517fc9Smrgstatic int
2017fe517fc9Smrgdrm_intel_gem_bo_add_softpin_target(drm_intel_bo *bo, drm_intel_bo *target_bo)
2018fe517fc9Smrg{
2019fe517fc9Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
2020fe517fc9Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
2021fe517fc9Smrg	drm_intel_bo_gem *target_bo_gem = (drm_intel_bo_gem *) target_bo;
2022fe517fc9Smrg	if (bo_gem->has_error)
2023fe517fc9Smrg		return -ENOMEM;
2024fe517fc9Smrg
2025fe517fc9Smrg	if (target_bo_gem->has_error) {
2026fe517fc9Smrg		bo_gem->has_error = true;
2027fe517fc9Smrg		return -ENOMEM;
2028fe517fc9Smrg	}
2029fe517fc9Smrg
2030fe517fc9Smrg	if (!target_bo_gem->is_softpin)
2031fe517fc9Smrg		return -EINVAL;
2032fe517fc9Smrg	if (target_bo_gem == bo_gem)
2033fe517fc9Smrg		return -EINVAL;
2034fe517fc9Smrg
2035fe517fc9Smrg	if (bo_gem->softpin_target_count == bo_gem->softpin_target_size) {
2036fe517fc9Smrg		int new_size = bo_gem->softpin_target_size * 2;
2037fe517fc9Smrg		if (new_size == 0)
2038fe517fc9Smrg			new_size = bufmgr_gem->max_relocs;
2039fe517fc9Smrg
2040fe517fc9Smrg		bo_gem->softpin_target = realloc(bo_gem->softpin_target, new_size *
2041fe517fc9Smrg				sizeof(drm_intel_bo *));
2042fe517fc9Smrg		if (!bo_gem->softpin_target)
2043fe517fc9Smrg			return -ENOMEM;
2044fe517fc9Smrg
2045fe517fc9Smrg		bo_gem->softpin_target_size = new_size;
2046fe517fc9Smrg	}
2047fe517fc9Smrg	bo_gem->softpin_target[bo_gem->softpin_target_count] = target_bo;
2048fe517fc9Smrg	drm_intel_gem_bo_reference(target_bo);
2049fe517fc9Smrg	bo_gem->softpin_target_count++;
2050fe517fc9Smrg
2051fe517fc9Smrg	return 0;
2052fe517fc9Smrg}
2053fe517fc9Smrg
205422944501Smrgstatic int
205522944501Smrgdrm_intel_gem_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
205622944501Smrg			    drm_intel_bo *target_bo, uint32_t target_offset,
205722944501Smrg			    uint32_t read_domains, uint32_t write_domain)
205822944501Smrg{
205922944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo->bufmgr;
2060fe517fc9Smrg	drm_intel_bo_gem *target_bo_gem = (drm_intel_bo_gem *)target_bo;
206122944501Smrg
2062fe517fc9Smrg	if (target_bo_gem->is_softpin)
2063fe517fc9Smrg		return drm_intel_gem_bo_add_softpin_target(bo, target_bo);
2064fe517fc9Smrg	else
2065fe517fc9Smrg		return do_bo_emit_reloc(bo, offset, target_bo, target_offset,
2066fe517fc9Smrg					read_domains, write_domain,
2067fe517fc9Smrg					!bufmgr_gem->fenced_relocs);
206822944501Smrg}
206922944501Smrg
207022944501Smrgstatic int
207122944501Smrgdrm_intel_gem_bo_emit_reloc_fence(drm_intel_bo *bo, uint32_t offset,
207222944501Smrg				  drm_intel_bo *target_bo,
207322944501Smrg				  uint32_t target_offset,
207422944501Smrg				  uint32_t read_domains, uint32_t write_domain)
207522944501Smrg{
207622944501Smrg	return do_bo_emit_reloc(bo, offset, target_bo, target_offset,
207720131375Smrg				read_domains, write_domain, true);
207820131375Smrg}
207920131375Smrg
2080424e9256Smrgint
208120131375Smrgdrm_intel_gem_bo_get_reloc_count(drm_intel_bo *bo)
208220131375Smrg{
208320131375Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
208420131375Smrg
208520131375Smrg	return bo_gem->reloc_count;
208620131375Smrg}
208720131375Smrg
208820131375Smrg/**
208920131375Smrg * Removes existing relocation entries in the BO after "start".
209020131375Smrg *
209120131375Smrg * This allows a user to avoid a two-step process for state setup with
209220131375Smrg * counting up all the buffer objects and doing a
209320131375Smrg * drm_intel_bufmgr_check_aperture_space() before emitting any of the
209420131375Smrg * relocations for the state setup.  Instead, save the state of the
209520131375Smrg * batchbuffer including drm_intel_gem_get_reloc_count(), emit all the
209620131375Smrg * state, and then check if it still fits in the aperture.
209720131375Smrg *
209820131375Smrg * Any further drm_intel_bufmgr_check_aperture_space() queries
209920131375Smrg * involving this buffer in the tree are undefined after this call.
2100fe517fc9Smrg *
2101fe517fc9Smrg * This also removes all softpinned targets being referenced by the BO.
210220131375Smrg */
2103424e9256Smrgvoid
210420131375Smrgdrm_intel_gem_bo_clear_relocs(drm_intel_bo *bo, int start)
210520131375Smrg{
2106a884aba1Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
210720131375Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
210820131375Smrg	int i;
210920131375Smrg	struct timespec time;
211020131375Smrg
211120131375Smrg	clock_gettime(CLOCK_MONOTONIC, &time);
211220131375Smrg
211320131375Smrg	assert(bo_gem->reloc_count >= start);
2114a884aba1Smrg
211520131375Smrg	/* Unreference the cleared target buffers */
2116a884aba1Smrg	pthread_mutex_lock(&bufmgr_gem->lock);
2117a884aba1Smrg
211820131375Smrg	for (i = start; i < bo_gem->reloc_count; i++) {
211920131375Smrg		drm_intel_bo_gem *target_bo_gem = (drm_intel_bo_gem *) bo_gem->reloc_target_info[i].bo;
212020131375Smrg		if (&target_bo_gem->bo != bo) {
212120131375Smrg			bo_gem->reloc_tree_fences -= target_bo_gem->reloc_tree_fences;
212220131375Smrg			drm_intel_gem_bo_unreference_locked_timed(&target_bo_gem->bo,
212320131375Smrg								  time.tv_sec);
212420131375Smrg		}
212520131375Smrg	}
212620131375Smrg	bo_gem->reloc_count = start;
2127a884aba1Smrg
2128fe517fc9Smrg	for (i = 0; i < bo_gem->softpin_target_count; i++) {
2129fe517fc9Smrg		drm_intel_bo_gem *target_bo_gem = (drm_intel_bo_gem *) bo_gem->softpin_target[i];
2130fe517fc9Smrg		drm_intel_gem_bo_unreference_locked_timed(&target_bo_gem->bo, time.tv_sec);
2131fe517fc9Smrg	}
2132fe517fc9Smrg	bo_gem->softpin_target_count = 0;
2133fe517fc9Smrg
2134a884aba1Smrg	pthread_mutex_unlock(&bufmgr_gem->lock);
2135a884aba1Smrg
213622944501Smrg}
213722944501Smrg
213822944501Smrg/**
213922944501Smrg * Walk the tree of relocations rooted at BO and accumulate the list of
214022944501Smrg * validations to be performed and update the relocation buffers with
214122944501Smrg * index values into the validation list.
214222944501Smrg */
214322944501Smrgstatic void
214422944501Smrgdrm_intel_gem_bo_process_reloc(drm_intel_bo *bo)
214522944501Smrg{
214622944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
214722944501Smrg	int i;
214822944501Smrg
214922944501Smrg	if (bo_gem->relocs == NULL)
215022944501Smrg		return;
215122944501Smrg
215222944501Smrg	for (i = 0; i < bo_gem->reloc_count; i++) {
215322944501Smrg		drm_intel_bo *target_bo = bo_gem->reloc_target_info[i].bo;
215422944501Smrg
2155aaba2545Smrg		if (target_bo == bo)
2156aaba2545Smrg			continue;
2157aaba2545Smrg
215820131375Smrg		drm_intel_gem_bo_mark_mmaps_incoherent(bo);
215920131375Smrg
216022944501Smrg		/* Continue walking the tree depth-first. */
216122944501Smrg		drm_intel_gem_bo_process_reloc(target_bo);
216222944501Smrg
216322944501Smrg		/* Add the target to the validate list */
216422944501Smrg		drm_intel_add_validate_buffer(target_bo);
216522944501Smrg	}
216622944501Smrg}
216722944501Smrg
216822944501Smrgstatic void
216922944501Smrgdrm_intel_gem_bo_process_reloc2(drm_intel_bo *bo)
217022944501Smrg{
217122944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
217222944501Smrg	int i;
217322944501Smrg
2174fe517fc9Smrg	if (bo_gem->relocs == NULL && bo_gem->softpin_target == NULL)
217522944501Smrg		return;
217622944501Smrg
217722944501Smrg	for (i = 0; i < bo_gem->reloc_count; i++) {
217822944501Smrg		drm_intel_bo *target_bo = bo_gem->reloc_target_info[i].bo;
217922944501Smrg		int need_fence;
218022944501Smrg
2181aaba2545Smrg		if (target_bo == bo)
2182aaba2545Smrg			continue;
2183aaba2545Smrg
218420131375Smrg		drm_intel_gem_bo_mark_mmaps_incoherent(bo);
218520131375Smrg
218622944501Smrg		/* Continue walking the tree depth-first. */
218722944501Smrg		drm_intel_gem_bo_process_reloc2(target_bo);
218822944501Smrg
218922944501Smrg		need_fence = (bo_gem->reloc_target_info[i].flags &
219022944501Smrg			      DRM_INTEL_RELOC_FENCE);
219122944501Smrg
219222944501Smrg		/* Add the target to the validate list */
219322944501Smrg		drm_intel_add_validate_buffer2(target_bo, need_fence);
219422944501Smrg	}
2195fe517fc9Smrg
2196fe517fc9Smrg	for (i = 0; i < bo_gem->softpin_target_count; i++) {
2197fe517fc9Smrg		drm_intel_bo *target_bo = bo_gem->softpin_target[i];
2198fe517fc9Smrg
2199fe517fc9Smrg		if (target_bo == bo)
2200fe517fc9Smrg			continue;
2201fe517fc9Smrg
2202fe517fc9Smrg		drm_intel_gem_bo_mark_mmaps_incoherent(bo);
2203fe517fc9Smrg		drm_intel_gem_bo_process_reloc2(target_bo);
2204fe517fc9Smrg		drm_intel_add_validate_buffer2(target_bo, false);
2205fe517fc9Smrg	}
220622944501Smrg}
220722944501Smrg
220822944501Smrg
220922944501Smrgstatic void
221022944501Smrgdrm_intel_update_buffer_offsets(drm_intel_bufmgr_gem *bufmgr_gem)
221122944501Smrg{
221222944501Smrg	int i;
221322944501Smrg
221422944501Smrg	for (i = 0; i < bufmgr_gem->exec_count; i++) {
221522944501Smrg		drm_intel_bo *bo = bufmgr_gem->exec_bos[i];
221622944501Smrg		drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
221722944501Smrg
221822944501Smrg		/* Update the buffer offset */
221920131375Smrg		if (bufmgr_gem->exec_objects[i].offset != bo->offset64) {
2220fe517fc9Smrg			DBG("BO %d (%s) migrated: 0x%08x %08x -> 0x%08x %08x\n",
2221d82d45b3Sjoerg			    bo_gem->gem_handle, bo_gem->name,
2222fe517fc9Smrg			    upper_32_bits(bo->offset64),
2223fe517fc9Smrg			    lower_32_bits(bo->offset64),
2224fe517fc9Smrg			    upper_32_bits(bufmgr_gem->exec_objects[i].offset),
2225fe517fc9Smrg			    lower_32_bits(bufmgr_gem->exec_objects[i].offset));
222620131375Smrg			bo->offset64 = bufmgr_gem->exec_objects[i].offset;
222722944501Smrg			bo->offset = bufmgr_gem->exec_objects[i].offset;
222822944501Smrg		}
222922944501Smrg	}
223022944501Smrg}
223122944501Smrg
223222944501Smrgstatic void
223322944501Smrgdrm_intel_update_buffer_offsets2 (drm_intel_bufmgr_gem *bufmgr_gem)
223422944501Smrg{
223522944501Smrg	int i;
223622944501Smrg
223722944501Smrg	for (i = 0; i < bufmgr_gem->exec_count; i++) {
223822944501Smrg		drm_intel_bo *bo = bufmgr_gem->exec_bos[i];
223922944501Smrg		drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
224022944501Smrg
224122944501Smrg		/* Update the buffer offset */
224220131375Smrg		if (bufmgr_gem->exec2_objects[i].offset != bo->offset64) {
2243fe517fc9Smrg			/* If we're seeing softpinned object here it means that the kernel
2244fe517fc9Smrg			 * has relocated our object... Indicating a programming error
2245fe517fc9Smrg			 */
2246fe517fc9Smrg			assert(!bo_gem->is_softpin);
2247fe517fc9Smrg			DBG("BO %d (%s) migrated: 0x%08x %08x -> 0x%08x %08x\n",
2248d82d45b3Sjoerg			    bo_gem->gem_handle, bo_gem->name,
2249fe517fc9Smrg			    upper_32_bits(bo->offset64),
2250fe517fc9Smrg			    lower_32_bits(bo->offset64),
2251fe517fc9Smrg			    upper_32_bits(bufmgr_gem->exec2_objects[i].offset),
2252fe517fc9Smrg			    lower_32_bits(bufmgr_gem->exec2_objects[i].offset));
225320131375Smrg			bo->offset64 = bufmgr_gem->exec2_objects[i].offset;
225422944501Smrg			bo->offset = bufmgr_gem->exec2_objects[i].offset;
225522944501Smrg		}
225622944501Smrg	}
225722944501Smrg}
225822944501Smrg
2259424e9256Smrgvoid
226020131375Smrgdrm_intel_gem_bo_aub_dump_bmp(drm_intel_bo *bo,
226120131375Smrg			      int x1, int y1, int width, int height,
226220131375Smrg			      enum aub_dump_bmp_format format,
226320131375Smrg			      int pitch, int offset)
226420131375Smrg{
226520131375Smrg}
226620131375Smrg
226720131375Smrgstatic int
226820131375Smrgdrm_intel_gem_bo_exec(drm_intel_bo *bo, int used,
226920131375Smrg		      drm_clip_rect_t * cliprects, int num_cliprects, int DR4)
227020131375Smrg{
227120131375Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
227220131375Smrg	struct drm_i915_gem_execbuffer execbuf;
227320131375Smrg	int ret, i;
227420131375Smrg
2275fe517fc9Smrg	if (to_bo_gem(bo)->has_error)
227620131375Smrg		return -ENOMEM;
227720131375Smrg
227820131375Smrg	pthread_mutex_lock(&bufmgr_gem->lock);
227920131375Smrg	/* Update indices and set up the validate list. */
228020131375Smrg	drm_intel_gem_bo_process_reloc(bo);
228120131375Smrg
228220131375Smrg	/* Add the batch buffer to the validation list.  There are no
228320131375Smrg	 * relocations pointing to it.
228420131375Smrg	 */
228520131375Smrg	drm_intel_add_validate_buffer(bo);
228620131375Smrg
2287424e9256Smrg	memclear(execbuf);
228820131375Smrg	execbuf.buffers_ptr = (uintptr_t) bufmgr_gem->exec_objects;
228920131375Smrg	execbuf.buffer_count = bufmgr_gem->exec_count;
229020131375Smrg	execbuf.batch_start_offset = 0;
229120131375Smrg	execbuf.batch_len = used;
229220131375Smrg	execbuf.cliprects_ptr = (uintptr_t) cliprects;
229320131375Smrg	execbuf.num_cliprects = num_cliprects;
229420131375Smrg	execbuf.DR1 = 0;
229520131375Smrg	execbuf.DR4 = DR4;
229620131375Smrg
229720131375Smrg	ret = drmIoctl(bufmgr_gem->fd,
229820131375Smrg		       DRM_IOCTL_I915_GEM_EXECBUFFER,
229920131375Smrg		       &execbuf);
230020131375Smrg	if (ret != 0) {
230120131375Smrg		ret = -errno;
230220131375Smrg		if (errno == ENOSPC) {
230320131375Smrg			DBG("Execbuffer fails to pin. "
230420131375Smrg			    "Estimate: %u. Actual: %u. Available: %u\n",
230520131375Smrg			    drm_intel_gem_estimate_batch_space(bufmgr_gem->exec_bos,
230620131375Smrg							       bufmgr_gem->
230720131375Smrg							       exec_count),
230820131375Smrg			    drm_intel_gem_compute_batch_space(bufmgr_gem->exec_bos,
230920131375Smrg							      bufmgr_gem->
231020131375Smrg							      exec_count),
231120131375Smrg			    (unsigned int)bufmgr_gem->gtt_size);
231220131375Smrg		}
231320131375Smrg	}
231420131375Smrg	drm_intel_update_buffer_offsets(bufmgr_gem);
231520131375Smrg
231620131375Smrg	if (bufmgr_gem->bufmgr.debug)
231720131375Smrg		drm_intel_gem_dump_validation_list(bufmgr_gem);
231820131375Smrg
231920131375Smrg	for (i = 0; i < bufmgr_gem->exec_count; i++) {
2320fe517fc9Smrg		drm_intel_bo_gem *bo_gem = to_bo_gem(bufmgr_gem->exec_bos[i]);
232120131375Smrg
232220131375Smrg		bo_gem->idle = false;
232320131375Smrg
232420131375Smrg		/* Disconnect the buffer from the validate list */
232520131375Smrg		bo_gem->validate_index = -1;
232620131375Smrg		bufmgr_gem->exec_bos[i] = NULL;
232720131375Smrg	}
232820131375Smrg	bufmgr_gem->exec_count = 0;
232920131375Smrg	pthread_mutex_unlock(&bufmgr_gem->lock);
233020131375Smrg
233120131375Smrg	return ret;
233220131375Smrg}
233320131375Smrg
233420131375Smrgstatic int
233520131375Smrgdo_exec2(drm_intel_bo *bo, int used, drm_intel_context *ctx,
233620131375Smrg	 drm_clip_rect_t *cliprects, int num_cliprects, int DR4,
233720131375Smrg	 unsigned int flags)
233820131375Smrg{
233920131375Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo->bufmgr;
234020131375Smrg	struct drm_i915_gem_execbuffer2 execbuf;
234120131375Smrg	int ret = 0;
234220131375Smrg	int i;
234320131375Smrg
2344fe517fc9Smrg	if (to_bo_gem(bo)->has_error)
2345fe517fc9Smrg		return -ENOMEM;
2346fe517fc9Smrg
234720131375Smrg	switch (flags & 0x7) {
234820131375Smrg	default:
234920131375Smrg		return -EINVAL;
235020131375Smrg	case I915_EXEC_BLT:
23519ce4edccSmrg		if (!bufmgr_gem->has_blt)
23529ce4edccSmrg			return -EINVAL;
23539ce4edccSmrg		break;
23549ce4edccSmrg	case I915_EXEC_BSD:
23559ce4edccSmrg		if (!bufmgr_gem->has_bsd)
23569ce4edccSmrg			return -EINVAL;
23579ce4edccSmrg		break;
235820131375Smrg	case I915_EXEC_VEBOX:
235920131375Smrg		if (!bufmgr_gem->has_vebox)
236020131375Smrg			return -EINVAL;
236120131375Smrg		break;
23629ce4edccSmrg	case I915_EXEC_RENDER:
23639ce4edccSmrg	case I915_EXEC_DEFAULT:
23649ce4edccSmrg		break;
23659ce4edccSmrg	}
2366aaba2545Smrg
236722944501Smrg	pthread_mutex_lock(&bufmgr_gem->lock);
236822944501Smrg	/* Update indices and set up the validate list. */
236922944501Smrg	drm_intel_gem_bo_process_reloc2(bo);
237022944501Smrg
237122944501Smrg	/* Add the batch buffer to the validation list.  There are no relocations
237222944501Smrg	 * pointing to it.
237322944501Smrg	 */
237422944501Smrg	drm_intel_add_validate_buffer2(bo, 0);
237522944501Smrg
2376424e9256Smrg	memclear(execbuf);
237722944501Smrg	execbuf.buffers_ptr = (uintptr_t)bufmgr_gem->exec2_objects;
237822944501Smrg	execbuf.buffer_count = bufmgr_gem->exec_count;
237922944501Smrg	execbuf.batch_start_offset = 0;
238022944501Smrg	execbuf.batch_len = used;
238122944501Smrg	execbuf.cliprects_ptr = (uintptr_t)cliprects;
238222944501Smrg	execbuf.num_cliprects = num_cliprects;
238322944501Smrg	execbuf.DR1 = 0;
238422944501Smrg	execbuf.DR4 = DR4;
238520131375Smrg	execbuf.flags = flags;
238620131375Smrg	if (ctx == NULL)
238720131375Smrg		i915_execbuffer2_set_context_id(execbuf, 0);
238820131375Smrg	else
238920131375Smrg		i915_execbuffer2_set_context_id(execbuf, ctx->ctx_id);
239022944501Smrg	execbuf.rsvd2 = 0;
239122944501Smrg
239220131375Smrg	if (bufmgr_gem->no_exec)
239320131375Smrg		goto skip_execution;
239420131375Smrg
23956d98c517Smrg	ret = drmIoctl(bufmgr_gem->fd,
23966d98c517Smrg		       DRM_IOCTL_I915_GEM_EXECBUFFER2,
23976d98c517Smrg		       &execbuf);
239822944501Smrg	if (ret != 0) {
239922944501Smrg		ret = -errno;
24006d98c517Smrg		if (ret == -ENOSPC) {
24019ce4edccSmrg			DBG("Execbuffer fails to pin. "
24029ce4edccSmrg			    "Estimate: %u. Actual: %u. Available: %u\n",
24039ce4edccSmrg			    drm_intel_gem_estimate_batch_space(bufmgr_gem->exec_bos,
24049ce4edccSmrg							       bufmgr_gem->exec_count),
24059ce4edccSmrg			    drm_intel_gem_compute_batch_space(bufmgr_gem->exec_bos,
24069ce4edccSmrg							      bufmgr_gem->exec_count),
24079ce4edccSmrg			    (unsigned int) bufmgr_gem->gtt_size);
240822944501Smrg		}
240922944501Smrg	}
241022944501Smrg	drm_intel_update_buffer_offsets2(bufmgr_gem);
241122944501Smrg
241220131375Smrgskip_execution:
241322944501Smrg	if (bufmgr_gem->bufmgr.debug)
241422944501Smrg		drm_intel_gem_dump_validation_list(bufmgr_gem);
241522944501Smrg
241622944501Smrg	for (i = 0; i < bufmgr_gem->exec_count; i++) {
2417fe517fc9Smrg		drm_intel_bo_gem *bo_gem = to_bo_gem(bufmgr_gem->exec_bos[i]);
241822944501Smrg
241920131375Smrg		bo_gem->idle = false;
242020131375Smrg
242122944501Smrg		/* Disconnect the buffer from the validate list */
242222944501Smrg		bo_gem->validate_index = -1;
242322944501Smrg		bufmgr_gem->exec_bos[i] = NULL;
242422944501Smrg	}
242522944501Smrg	bufmgr_gem->exec_count = 0;
242622944501Smrg	pthread_mutex_unlock(&bufmgr_gem->lock);
242722944501Smrg
242822944501Smrg	return ret;
242922944501Smrg}
243022944501Smrg
2431aaba2545Smrgstatic int
2432aaba2545Smrgdrm_intel_gem_bo_exec2(drm_intel_bo *bo, int used,
2433aaba2545Smrg		       drm_clip_rect_t *cliprects, int num_cliprects,
2434aaba2545Smrg		       int DR4)
2435aaba2545Smrg{
243620131375Smrg	return do_exec2(bo, used, NULL, cliprects, num_cliprects, DR4,
243720131375Smrg			I915_EXEC_RENDER);
243820131375Smrg}
243920131375Smrg
244020131375Smrgstatic int
244120131375Smrgdrm_intel_gem_bo_mrb_exec2(drm_intel_bo *bo, int used,
244220131375Smrg			drm_clip_rect_t *cliprects, int num_cliprects, int DR4,
244320131375Smrg			unsigned int flags)
244420131375Smrg{
244520131375Smrg	return do_exec2(bo, used, NULL, cliprects, num_cliprects, DR4,
244620131375Smrg			flags);
244720131375Smrg}
244820131375Smrg
2449424e9256Smrgint
245020131375Smrgdrm_intel_gem_bo_context_exec(drm_intel_bo *bo, drm_intel_context *ctx,
245120131375Smrg			      int used, unsigned int flags)
245220131375Smrg{
245320131375Smrg	return do_exec2(bo, used, ctx, NULL, 0, 0, flags);
2454aaba2545Smrg}
2455aaba2545Smrg
245622944501Smrgstatic int
245722944501Smrgdrm_intel_gem_bo_pin(drm_intel_bo *bo, uint32_t alignment)
245822944501Smrg{
245922944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
246022944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
246122944501Smrg	struct drm_i915_gem_pin pin;
246222944501Smrg	int ret;
246322944501Smrg
2464424e9256Smrg	memclear(pin);
246522944501Smrg	pin.handle = bo_gem->gem_handle;
246622944501Smrg	pin.alignment = alignment;
246722944501Smrg
24686d98c517Smrg	ret = drmIoctl(bufmgr_gem->fd,
24696d98c517Smrg		       DRM_IOCTL_I915_GEM_PIN,
24706d98c517Smrg		       &pin);
247122944501Smrg	if (ret != 0)
247222944501Smrg		return -errno;
247322944501Smrg
247420131375Smrg	bo->offset64 = pin.offset;
247522944501Smrg	bo->offset = pin.offset;
247622944501Smrg	return 0;
247722944501Smrg}
247822944501Smrg
247922944501Smrgstatic int
248022944501Smrgdrm_intel_gem_bo_unpin(drm_intel_bo *bo)
248122944501Smrg{
248222944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
248322944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
248422944501Smrg	struct drm_i915_gem_unpin unpin;
248522944501Smrg	int ret;
248622944501Smrg
2487424e9256Smrg	memclear(unpin);
248822944501Smrg	unpin.handle = bo_gem->gem_handle;
248922944501Smrg
24906d98c517Smrg	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_UNPIN, &unpin);
249122944501Smrg	if (ret != 0)
249222944501Smrg		return -errno;
249322944501Smrg
249422944501Smrg	return 0;
249522944501Smrg}
249622944501Smrg
249722944501Smrgstatic int
24986d98c517Smrgdrm_intel_gem_bo_set_tiling_internal(drm_intel_bo *bo,
24996d98c517Smrg				     uint32_t tiling_mode,
25006d98c517Smrg				     uint32_t stride)
250122944501Smrg{
250222944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
250322944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
250422944501Smrg	struct drm_i915_gem_set_tiling set_tiling;
250522944501Smrg	int ret;
250622944501Smrg
25076d98c517Smrg	if (bo_gem->global_name == 0 &&
25086d98c517Smrg	    tiling_mode == bo_gem->tiling_mode &&
25096d98c517Smrg	    stride == bo_gem->stride)
251022944501Smrg		return 0;
251122944501Smrg
251222944501Smrg	memset(&set_tiling, 0, sizeof(set_tiling));
251322944501Smrg	do {
25146d98c517Smrg		/* set_tiling is slightly broken and overwrites the
25156d98c517Smrg		 * input on the error path, so we have to open code
25166d98c517Smrg		 * rmIoctl.
25176d98c517Smrg		 */
25186d98c517Smrg		set_tiling.handle = bo_gem->gem_handle;
25196d98c517Smrg		set_tiling.tiling_mode = tiling_mode;
252022944501Smrg		set_tiling.stride = stride;
252122944501Smrg
252222944501Smrg		ret = ioctl(bufmgr_gem->fd,
252322944501Smrg			    DRM_IOCTL_I915_GEM_SET_TILING,
252422944501Smrg			    &set_tiling);
25256d98c517Smrg	} while (ret == -1 && (errno == EINTR || errno == EAGAIN));
25266d98c517Smrg	if (ret == -1)
25276d98c517Smrg		return -errno;
25286d98c517Smrg
25296d98c517Smrg	bo_gem->tiling_mode = set_tiling.tiling_mode;
25306d98c517Smrg	bo_gem->swizzle_mode = set_tiling.swizzle_mode;
25316d98c517Smrg	bo_gem->stride = set_tiling.stride;
25326d98c517Smrg	return 0;
25336d98c517Smrg}
25346d98c517Smrg
25356d98c517Smrgstatic int
25366d98c517Smrgdrm_intel_gem_bo_set_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
25376d98c517Smrg			    uint32_t stride)
25386d98c517Smrg{
25396d98c517Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
25406d98c517Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
25416d98c517Smrg	int ret;
25426d98c517Smrg
2543a884aba1Smrg	/* Tiling with userptr surfaces is not supported
2544a884aba1Smrg	 * on all hardware so refuse it for time being.
2545a884aba1Smrg	 */
2546a884aba1Smrg	if (bo_gem->is_userptr)
2547a884aba1Smrg		return -EINVAL;
2548a884aba1Smrg
25496d98c517Smrg	/* Linear buffers have no stride. By ensuring that we only ever use
25506d98c517Smrg	 * stride 0 with linear buffers, we simplify our code.
25516d98c517Smrg	 */
25526d98c517Smrg	if (*tiling_mode == I915_TILING_NONE)
25536d98c517Smrg		stride = 0;
25546d98c517Smrg
25556d98c517Smrg	ret = drm_intel_gem_bo_set_tiling_internal(bo, *tiling_mode, stride);
25566d98c517Smrg	if (ret == 0)
2557fe517fc9Smrg		drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, 0);
255822944501Smrg
255922944501Smrg	*tiling_mode = bo_gem->tiling_mode;
2560aaba2545Smrg	return ret;
256122944501Smrg}
256222944501Smrg
256322944501Smrgstatic int
256422944501Smrgdrm_intel_gem_bo_get_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
256522944501Smrg			    uint32_t * swizzle_mode)
256622944501Smrg{
256722944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
256822944501Smrg
256922944501Smrg	*tiling_mode = bo_gem->tiling_mode;
257022944501Smrg	*swizzle_mode = bo_gem->swizzle_mode;
257122944501Smrg	return 0;
257222944501Smrg}
257322944501Smrg
2574fe517fc9Smrgstatic int
2575fe517fc9Smrgdrm_intel_gem_bo_set_softpin_offset(drm_intel_bo *bo, uint64_t offset)
2576fe517fc9Smrg{
2577fe517fc9Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
2578fe517fc9Smrg
2579fe517fc9Smrg	bo_gem->is_softpin = true;
2580fe517fc9Smrg	bo->offset64 = offset;
2581fe517fc9Smrg	bo->offset = offset;
2582fe517fc9Smrg	return 0;
2583fe517fc9Smrg}
2584fe517fc9Smrg
2585424e9256Smrgdrm_intel_bo *
258620131375Smrgdrm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr, int prime_fd, int size)
258720131375Smrg{
258820131375Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
258920131375Smrg	int ret;
259020131375Smrg	uint32_t handle;
259120131375Smrg	drm_intel_bo_gem *bo_gem;
259220131375Smrg	struct drm_i915_gem_get_tiling get_tiling;
259320131375Smrg	drmMMListHead *list;
259420131375Smrg
2595fe517fc9Smrg	pthread_mutex_lock(&bufmgr_gem->lock);
259620131375Smrg	ret = drmPrimeFDToHandle(bufmgr_gem->fd, prime_fd, &handle);
2597fe517fc9Smrg	if (ret) {
2598fe517fc9Smrg		DBG("create_from_prime: failed to obtain handle from fd: %s\n", strerror(errno));
2599fe517fc9Smrg		pthread_mutex_unlock(&bufmgr_gem->lock);
2600fe517fc9Smrg		return NULL;
2601fe517fc9Smrg	}
260220131375Smrg
260320131375Smrg	/*
260420131375Smrg	 * See if the kernel has already returned this buffer to us. Just as
260520131375Smrg	 * for named buffers, we must not create two bo's pointing at the same
260620131375Smrg	 * kernel object
260720131375Smrg	 */
260820131375Smrg	for (list = bufmgr_gem->named.next;
260920131375Smrg	     list != &bufmgr_gem->named;
261020131375Smrg	     list = list->next) {
261120131375Smrg		bo_gem = DRMLISTENTRY(drm_intel_bo_gem, list, name_list);
261220131375Smrg		if (bo_gem->gem_handle == handle) {
261320131375Smrg			drm_intel_gem_bo_reference(&bo_gem->bo);
2614a884aba1Smrg			pthread_mutex_unlock(&bufmgr_gem->lock);
261520131375Smrg			return &bo_gem->bo;
261620131375Smrg		}
261720131375Smrg	}
261820131375Smrg
261920131375Smrg	bo_gem = calloc(1, sizeof(*bo_gem));
2620a884aba1Smrg	if (!bo_gem) {
2621a884aba1Smrg		pthread_mutex_unlock(&bufmgr_gem->lock);
262220131375Smrg		return NULL;
2623a884aba1Smrg	}
262420131375Smrg	/* Determine size of bo.  The fd-to-handle ioctl really should
262520131375Smrg	 * return the size, but it doesn't.  If we have kernel 3.12 or
262620131375Smrg	 * later, we can lseek on the prime fd to get the size.  Older
262720131375Smrg	 * kernels will just fail, in which case we fall back to the
262820131375Smrg	 * provided (estimated or guess size). */
262920131375Smrg	ret = lseek(prime_fd, 0, SEEK_END);
263020131375Smrg	if (ret != -1)
263120131375Smrg		bo_gem->bo.size = ret;
263220131375Smrg	else
263320131375Smrg		bo_gem->bo.size = size;
263420131375Smrg
263520131375Smrg	bo_gem->bo.handle = handle;
263620131375Smrg	bo_gem->bo.bufmgr = bufmgr;
263720131375Smrg
263820131375Smrg	bo_gem->gem_handle = handle;
263920131375Smrg
264020131375Smrg	atomic_set(&bo_gem->refcount, 1);
264120131375Smrg
264220131375Smrg	bo_gem->name = "prime";
264320131375Smrg	bo_gem->validate_index = -1;
264420131375Smrg	bo_gem->reloc_tree_fences = 0;
264520131375Smrg	bo_gem->used_as_reloc_target = false;
264620131375Smrg	bo_gem->has_error = false;
264720131375Smrg	bo_gem->reusable = false;
2648fe517fc9Smrg	bo_gem->use_48b_address_range = false;
264920131375Smrg
265020131375Smrg	DRMINITLISTHEAD(&bo_gem->vma_list);
265120131375Smrg	DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named);
2652a884aba1Smrg	pthread_mutex_unlock(&bufmgr_gem->lock);
265320131375Smrg
2654424e9256Smrg	memclear(get_tiling);
265520131375Smrg	get_tiling.handle = bo_gem->gem_handle;
265620131375Smrg	ret = drmIoctl(bufmgr_gem->fd,
265720131375Smrg		       DRM_IOCTL_I915_GEM_GET_TILING,
265820131375Smrg		       &get_tiling);
265920131375Smrg	if (ret != 0) {
2660fe517fc9Smrg		DBG("create_from_prime: failed to get tiling: %s\n", strerror(errno));
266120131375Smrg		drm_intel_gem_bo_unreference(&bo_gem->bo);
266220131375Smrg		return NULL;
266320131375Smrg	}
266420131375Smrg	bo_gem->tiling_mode = get_tiling.tiling_mode;
266520131375Smrg	bo_gem->swizzle_mode = get_tiling.swizzle_mode;
266620131375Smrg	/* XXX stride is unknown */
2667fe517fc9Smrg	drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, 0);
266820131375Smrg
266920131375Smrg	return &bo_gem->bo;
267020131375Smrg}
267120131375Smrg
2672424e9256Smrgint
267320131375Smrgdrm_intel_bo_gem_export_to_prime(drm_intel_bo *bo, int *prime_fd)
267420131375Smrg{
267520131375Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
267620131375Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
267720131375Smrg
2678a884aba1Smrg	pthread_mutex_lock(&bufmgr_gem->lock);
267920131375Smrg        if (DRMLISTEMPTY(&bo_gem->name_list))
268020131375Smrg                DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named);
2681a884aba1Smrg	pthread_mutex_unlock(&bufmgr_gem->lock);
268220131375Smrg
268320131375Smrg	if (drmPrimeHandleToFD(bufmgr_gem->fd, bo_gem->gem_handle,
268420131375Smrg			       DRM_CLOEXEC, prime_fd) != 0)
268520131375Smrg		return -errno;
268620131375Smrg
268720131375Smrg	bo_gem->reusable = false;
268820131375Smrg
268920131375Smrg	return 0;
269020131375Smrg}
269120131375Smrg
269222944501Smrgstatic int
269322944501Smrgdrm_intel_gem_bo_flink(drm_intel_bo *bo, uint32_t * name)
269422944501Smrg{
269522944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
269622944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
269722944501Smrg	int ret;
269822944501Smrg
269922944501Smrg	if (!bo_gem->global_name) {
270020131375Smrg		struct drm_gem_flink flink;
270120131375Smrg
2702424e9256Smrg		memclear(flink);
270322944501Smrg		flink.handle = bo_gem->gem_handle;
270422944501Smrg
2705a884aba1Smrg		pthread_mutex_lock(&bufmgr_gem->lock);
2706a884aba1Smrg
27076d98c517Smrg		ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_GEM_FLINK, &flink);
2708a884aba1Smrg		if (ret != 0) {
2709a884aba1Smrg			pthread_mutex_unlock(&bufmgr_gem->lock);
271022944501Smrg			return -errno;
2711a884aba1Smrg		}
271220131375Smrg
271322944501Smrg		bo_gem->global_name = flink.name;
271420131375Smrg		bo_gem->reusable = false;
271520131375Smrg
271620131375Smrg                if (DRMLISTEMPTY(&bo_gem->name_list))
271720131375Smrg                        DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named);
2718a884aba1Smrg		pthread_mutex_unlock(&bufmgr_gem->lock);
271922944501Smrg	}
272022944501Smrg
272122944501Smrg	*name = bo_gem->global_name;
272222944501Smrg	return 0;
272322944501Smrg}
272422944501Smrg
272522944501Smrg/**
272622944501Smrg * Enables unlimited caching of buffer objects for reuse.
272722944501Smrg *
272822944501Smrg * This is potentially very memory expensive, as the cache at each bucket
272922944501Smrg * size is only bounded by how many buffers of that size we've managed to have
273022944501Smrg * in flight at once.
273122944501Smrg */
2732424e9256Smrgvoid
273322944501Smrgdrm_intel_bufmgr_gem_enable_reuse(drm_intel_bufmgr *bufmgr)
273422944501Smrg{
273522944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
273622944501Smrg
273720131375Smrg	bufmgr_gem->bo_reuse = true;
273822944501Smrg}
273922944501Smrg
274022944501Smrg/**
274122944501Smrg * Enable use of fenced reloc type.
274222944501Smrg *
274322944501Smrg * New code should enable this to avoid unnecessary fence register
274422944501Smrg * allocation.  If this option is not enabled, all relocs will have fence
274522944501Smrg * register allocated.
274622944501Smrg */
2747424e9256Smrgvoid
274822944501Smrgdrm_intel_bufmgr_gem_enable_fenced_relocs(drm_intel_bufmgr *bufmgr)
274922944501Smrg{
275022944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
275122944501Smrg
275222944501Smrg	if (bufmgr_gem->bufmgr.bo_exec == drm_intel_gem_bo_exec2)
275320131375Smrg		bufmgr_gem->fenced_relocs = true;
275422944501Smrg}
275522944501Smrg
275622944501Smrg/**
275722944501Smrg * Return the additional aperture space required by the tree of buffer objects
275822944501Smrg * rooted at bo.
275922944501Smrg */
276022944501Smrgstatic int
276122944501Smrgdrm_intel_gem_bo_get_aperture_space(drm_intel_bo *bo)
276222944501Smrg{
276322944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
276422944501Smrg	int i;
276522944501Smrg	int total = 0;
276622944501Smrg
276722944501Smrg	if (bo == NULL || bo_gem->included_in_check_aperture)
276822944501Smrg		return 0;
276922944501Smrg
277022944501Smrg	total += bo->size;
277120131375Smrg	bo_gem->included_in_check_aperture = true;
277222944501Smrg
277322944501Smrg	for (i = 0; i < bo_gem->reloc_count; i++)
277422944501Smrg		total +=
277522944501Smrg		    drm_intel_gem_bo_get_aperture_space(bo_gem->
277622944501Smrg							reloc_target_info[i].bo);
277722944501Smrg
277822944501Smrg	return total;
277922944501Smrg}
278022944501Smrg
278122944501Smrg/**
278222944501Smrg * Count the number of buffers in this list that need a fence reg
278322944501Smrg *
278422944501Smrg * If the count is greater than the number of available regs, we'll have
278522944501Smrg * to ask the caller to resubmit a batch with fewer tiled buffers.
278622944501Smrg *
278722944501Smrg * This function over-counts if the same buffer is used multiple times.
278822944501Smrg */
278922944501Smrgstatic unsigned int
279022944501Smrgdrm_intel_gem_total_fences(drm_intel_bo ** bo_array, int count)
279122944501Smrg{
279222944501Smrg	int i;
279322944501Smrg	unsigned int total = 0;
279422944501Smrg
279522944501Smrg	for (i = 0; i < count; i++) {
279622944501Smrg		drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo_array[i];
279722944501Smrg
279822944501Smrg		if (bo_gem == NULL)
279922944501Smrg			continue;
280022944501Smrg
280122944501Smrg		total += bo_gem->reloc_tree_fences;
280222944501Smrg	}
280322944501Smrg	return total;
280422944501Smrg}
280522944501Smrg
280622944501Smrg/**
280722944501Smrg * Clear the flag set by drm_intel_gem_bo_get_aperture_space() so we're ready
280822944501Smrg * for the next drm_intel_bufmgr_check_aperture_space() call.
280922944501Smrg */
281022944501Smrgstatic void
281122944501Smrgdrm_intel_gem_bo_clear_aperture_space_flag(drm_intel_bo *bo)
281222944501Smrg{
281322944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
281422944501Smrg	int i;
281522944501Smrg
281622944501Smrg	if (bo == NULL || !bo_gem->included_in_check_aperture)
281722944501Smrg		return;
281822944501Smrg
281920131375Smrg	bo_gem->included_in_check_aperture = false;
282022944501Smrg
282122944501Smrg	for (i = 0; i < bo_gem->reloc_count; i++)
282222944501Smrg		drm_intel_gem_bo_clear_aperture_space_flag(bo_gem->
282322944501Smrg							   reloc_target_info[i].bo);
282422944501Smrg}
282522944501Smrg
282622944501Smrg/**
282722944501Smrg * Return a conservative estimate for the amount of aperture required
282822944501Smrg * for a collection of buffers. This may double-count some buffers.
282922944501Smrg */
283022944501Smrgstatic unsigned int
283122944501Smrgdrm_intel_gem_estimate_batch_space(drm_intel_bo **bo_array, int count)
283222944501Smrg{
283322944501Smrg	int i;
283422944501Smrg	unsigned int total = 0;
283522944501Smrg
283622944501Smrg	for (i = 0; i < count; i++) {
283722944501Smrg		drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo_array[i];
283822944501Smrg		if (bo_gem != NULL)
283922944501Smrg			total += bo_gem->reloc_tree_size;
284022944501Smrg	}
284122944501Smrg	return total;
284222944501Smrg}
284322944501Smrg
284422944501Smrg/**
284522944501Smrg * Return the amount of aperture needed for a collection of buffers.
284622944501Smrg * This avoids double counting any buffers, at the cost of looking
284722944501Smrg * at every buffer in the set.
284822944501Smrg */
284922944501Smrgstatic unsigned int
285022944501Smrgdrm_intel_gem_compute_batch_space(drm_intel_bo **bo_array, int count)
285122944501Smrg{
285222944501Smrg	int i;
285322944501Smrg	unsigned int total = 0;
285422944501Smrg
285522944501Smrg	for (i = 0; i < count; i++) {
285622944501Smrg		total += drm_intel_gem_bo_get_aperture_space(bo_array[i]);
285722944501Smrg		/* For the first buffer object in the array, we get an
285822944501Smrg		 * accurate count back for its reloc_tree size (since nothing
285922944501Smrg		 * had been flagged as being counted yet).  We can save that
286022944501Smrg		 * value out as a more conservative reloc_tree_size that
286122944501Smrg		 * avoids double-counting target buffers.  Since the first
286222944501Smrg		 * buffer happens to usually be the batch buffer in our
286322944501Smrg		 * callers, this can pull us back from doing the tree
286422944501Smrg		 * walk on every new batch emit.
286522944501Smrg		 */
286622944501Smrg		if (i == 0) {
286722944501Smrg			drm_intel_bo_gem *bo_gem =
286822944501Smrg			    (drm_intel_bo_gem *) bo_array[i];
286922944501Smrg			bo_gem->reloc_tree_size = total;
287022944501Smrg		}
287122944501Smrg	}
287222944501Smrg
287322944501Smrg	for (i = 0; i < count; i++)
287422944501Smrg		drm_intel_gem_bo_clear_aperture_space_flag(bo_array[i]);
287522944501Smrg	return total;
287622944501Smrg}
287722944501Smrg
287822944501Smrg/**
287922944501Smrg * Return -1 if the batchbuffer should be flushed before attempting to
288022944501Smrg * emit rendering referencing the buffers pointed to by bo_array.
288122944501Smrg *
288222944501Smrg * This is required because if we try to emit a batchbuffer with relocations
288322944501Smrg * to a tree of buffers that won't simultaneously fit in the aperture,
288422944501Smrg * the rendering will return an error at a point where the software is not
288522944501Smrg * prepared to recover from it.
288622944501Smrg *
288722944501Smrg * However, we also want to emit the batchbuffer significantly before we reach
288822944501Smrg * the limit, as a series of batchbuffers each of which references buffers
288922944501Smrg * covering almost all of the aperture means that at each emit we end up
289022944501Smrg * waiting to evict a buffer from the last rendering, and we get synchronous
289122944501Smrg * performance.  By emitting smaller batchbuffers, we eat some CPU overhead to
289222944501Smrg * get better parallelism.
289322944501Smrg */
289422944501Smrgstatic int
289522944501Smrgdrm_intel_gem_check_aperture_space(drm_intel_bo **bo_array, int count)
289622944501Smrg{
289722944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem =
289822944501Smrg	    (drm_intel_bufmgr_gem *) bo_array[0]->bufmgr;
289922944501Smrg	unsigned int total = 0;
290022944501Smrg	unsigned int threshold = bufmgr_gem->gtt_size * 3 / 4;
290122944501Smrg	int total_fences;
290222944501Smrg
290322944501Smrg	/* Check for fence reg constraints if necessary */
290422944501Smrg	if (bufmgr_gem->available_fences) {
290522944501Smrg		total_fences = drm_intel_gem_total_fences(bo_array, count);
290622944501Smrg		if (total_fences > bufmgr_gem->available_fences)
290722944501Smrg			return -ENOSPC;
290822944501Smrg	}
290922944501Smrg
291022944501Smrg	total = drm_intel_gem_estimate_batch_space(bo_array, count);
291122944501Smrg
291222944501Smrg	if (total > threshold)
291322944501Smrg		total = drm_intel_gem_compute_batch_space(bo_array, count);
291422944501Smrg
291522944501Smrg	if (total > threshold) {
291622944501Smrg		DBG("check_space: overflowed available aperture, "
291722944501Smrg		    "%dkb vs %dkb\n",
291822944501Smrg		    total / 1024, (int)bufmgr_gem->gtt_size / 1024);
291922944501Smrg		return -ENOSPC;
292022944501Smrg	} else {
292122944501Smrg		DBG("drm_check_space: total %dkb vs bufgr %dkb\n", total / 1024,
292222944501Smrg		    (int)bufmgr_gem->gtt_size / 1024);
292322944501Smrg		return 0;
292422944501Smrg	}
292522944501Smrg}
292622944501Smrg
292722944501Smrg/*
292822944501Smrg * Disable buffer reuse for objects which are shared with the kernel
292922944501Smrg * as scanout buffers
293022944501Smrg */
293122944501Smrgstatic int
293222944501Smrgdrm_intel_gem_bo_disable_reuse(drm_intel_bo *bo)
293322944501Smrg{
293422944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
293522944501Smrg
293620131375Smrg	bo_gem->reusable = false;
293722944501Smrg	return 0;
293822944501Smrg}
293922944501Smrg
2940aaba2545Smrgstatic int
2941aaba2545Smrgdrm_intel_gem_bo_is_reusable(drm_intel_bo *bo)
2942aaba2545Smrg{
2943aaba2545Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
2944aaba2545Smrg
2945aaba2545Smrg	return bo_gem->reusable;
2946aaba2545Smrg}
2947aaba2545Smrg
294822944501Smrgstatic int
294922944501Smrg_drm_intel_gem_bo_references(drm_intel_bo *bo, drm_intel_bo *target_bo)
295022944501Smrg{
295122944501Smrg	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
295222944501Smrg	int i;
295322944501Smrg
295422944501Smrg	for (i = 0; i < bo_gem->reloc_count; i++) {
295522944501Smrg		if (bo_gem->reloc_target_info[i].bo == target_bo)
295622944501Smrg			return 1;
2957aaba2545Smrg		if (bo == bo_gem->reloc_target_info[i].bo)
2958aaba2545Smrg			continue;
295922944501Smrg		if (_drm_intel_gem_bo_references(bo_gem->reloc_target_info[i].bo,
296022944501Smrg						target_bo))
296122944501Smrg			return 1;
296222944501Smrg	}
296322944501Smrg
2964fe517fc9Smrg	for (i = 0; i< bo_gem->softpin_target_count; i++) {
2965fe517fc9Smrg		if (bo_gem->softpin_target[i] == target_bo)
2966fe517fc9Smrg			return 1;
2967fe517fc9Smrg		if (_drm_intel_gem_bo_references(bo_gem->softpin_target[i], target_bo))
2968fe517fc9Smrg			return 1;
2969fe517fc9Smrg	}
2970fe517fc9Smrg
297122944501Smrg	return 0;
297222944501Smrg}
297322944501Smrg
297422944501Smrg/** Return true if target_bo is referenced by bo's relocation tree. */
297522944501Smrgstatic int
297622944501Smrgdrm_intel_gem_bo_references(drm_intel_bo *bo, drm_intel_bo *target_bo)
297722944501Smrg{
297822944501Smrg	drm_intel_bo_gem *target_bo_gem = (drm_intel_bo_gem *) target_bo;
297922944501Smrg
298022944501Smrg	if (bo == NULL || target_bo == NULL)
298122944501Smrg		return 0;
298222944501Smrg	if (target_bo_gem->used_as_reloc_target)
298322944501Smrg		return _drm_intel_gem_bo_references(bo, target_bo);
298422944501Smrg	return 0;
298522944501Smrg}
298622944501Smrg
2987aaba2545Smrgstatic void
2988aaba2545Smrgadd_bucket(drm_intel_bufmgr_gem *bufmgr_gem, int size)
2989aaba2545Smrg{
2990aaba2545Smrg	unsigned int i = bufmgr_gem->num_buckets;
2991aaba2545Smrg
2992aaba2545Smrg	assert(i < ARRAY_SIZE(bufmgr_gem->cache_bucket));
2993aaba2545Smrg
2994aaba2545Smrg	DRMINITLISTHEAD(&bufmgr_gem->cache_bucket[i].head);
2995aaba2545Smrg	bufmgr_gem->cache_bucket[i].size = size;
2996aaba2545Smrg	bufmgr_gem->num_buckets++;
2997aaba2545Smrg}
2998aaba2545Smrg
2999aaba2545Smrgstatic void
3000aaba2545Smrginit_cache_buckets(drm_intel_bufmgr_gem *bufmgr_gem)
3001aaba2545Smrg{
3002aaba2545Smrg	unsigned long size, cache_max_size = 64 * 1024 * 1024;
3003aaba2545Smrg
3004aaba2545Smrg	/* OK, so power of two buckets was too wasteful of memory.
3005aaba2545Smrg	 * Give 3 other sizes between each power of two, to hopefully
3006aaba2545Smrg	 * cover things accurately enough.  (The alternative is
3007aaba2545Smrg	 * probably to just go for exact matching of sizes, and assume
3008aaba2545Smrg	 * that for things like composited window resize the tiled
3009aaba2545Smrg	 * width/height alignment and rounding of sizes to pages will
3010aaba2545Smrg	 * get us useful cache hit rates anyway)
3011aaba2545Smrg	 */
3012aaba2545Smrg	add_bucket(bufmgr_gem, 4096);
3013aaba2545Smrg	add_bucket(bufmgr_gem, 4096 * 2);
3014aaba2545Smrg	add_bucket(bufmgr_gem, 4096 * 3);
3015aaba2545Smrg
3016aaba2545Smrg	/* Initialize the linked lists for BO reuse cache. */
3017aaba2545Smrg	for (size = 4 * 4096; size <= cache_max_size; size *= 2) {
3018aaba2545Smrg		add_bucket(bufmgr_gem, size);
3019aaba2545Smrg
3020aaba2545Smrg		add_bucket(bufmgr_gem, size + size * 1 / 4);
3021aaba2545Smrg		add_bucket(bufmgr_gem, size + size * 2 / 4);
3022aaba2545Smrg		add_bucket(bufmgr_gem, size + size * 3 / 4);
3023aaba2545Smrg	}
3024aaba2545Smrg}
3025aaba2545Smrg
3026424e9256Smrgvoid
302720131375Smrgdrm_intel_bufmgr_gem_set_vma_cache_size(drm_intel_bufmgr *bufmgr, int limit)
302820131375Smrg{
302920131375Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
303020131375Smrg
303120131375Smrg	bufmgr_gem->vma_max = limit;
303220131375Smrg
303320131375Smrg	drm_intel_gem_bo_purge_vma_cache(bufmgr_gem);
303420131375Smrg}
303520131375Smrg
303620131375Smrg/**
303720131375Smrg * Get the PCI ID for the device.  This can be overridden by setting the
303820131375Smrg * INTEL_DEVID_OVERRIDE environment variable to the desired ID.
303920131375Smrg */
304020131375Smrgstatic int
304120131375Smrgget_pci_device_id(drm_intel_bufmgr_gem *bufmgr_gem)
304220131375Smrg{
304320131375Smrg	char *devid_override;
3044424e9256Smrg	int devid = 0;
304520131375Smrg	int ret;
304620131375Smrg	drm_i915_getparam_t gp;
304720131375Smrg
304820131375Smrg	if (geteuid() == getuid()) {
304920131375Smrg		devid_override = getenv("INTEL_DEVID_OVERRIDE");
305020131375Smrg		if (devid_override) {
305120131375Smrg			bufmgr_gem->no_exec = true;
305220131375Smrg			return strtod(devid_override, NULL);
305320131375Smrg		}
305420131375Smrg	}
305520131375Smrg
3056424e9256Smrg	memclear(gp);
305720131375Smrg	gp.param = I915_PARAM_CHIPSET_ID;
305820131375Smrg	gp.value = &devid;
305920131375Smrg	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
306020131375Smrg	if (ret) {
306120131375Smrg		fprintf(stderr, "get chip id failed: %d [%d]\n", ret, errno);
306220131375Smrg		fprintf(stderr, "param: %d, val: %d\n", gp.param, *gp.value);
306320131375Smrg	}
306420131375Smrg	return devid;
306520131375Smrg}
306620131375Smrg
3067424e9256Smrgint
306820131375Smrgdrm_intel_bufmgr_gem_get_devid(drm_intel_bufmgr *bufmgr)
306920131375Smrg{
307020131375Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
307120131375Smrg
307220131375Smrg	return bufmgr_gem->pci_device;
307320131375Smrg}
307420131375Smrg
307520131375Smrg/**
307620131375Smrg * Sets the AUB filename.
307720131375Smrg *
307820131375Smrg * This function has to be called before drm_intel_bufmgr_gem_set_aub_dump()
307920131375Smrg * for it to have any effect.
308020131375Smrg */
3081424e9256Smrgvoid
308220131375Smrgdrm_intel_bufmgr_gem_set_aub_filename(drm_intel_bufmgr *bufmgr,
308320131375Smrg				      const char *filename)
308420131375Smrg{
308520131375Smrg}
308620131375Smrg
308720131375Smrg/**
308820131375Smrg * Sets up AUB dumping.
308920131375Smrg *
309020131375Smrg * This is a trace file format that can be used with the simulator.
309120131375Smrg * Packets are emitted in a format somewhat like GPU command packets.
309220131375Smrg * You can set up a GTT and upload your objects into the referenced
309320131375Smrg * space, then send off batchbuffers and get BMPs out the other end.
309420131375Smrg */
3095424e9256Smrgvoid
309620131375Smrgdrm_intel_bufmgr_gem_set_aub_dump(drm_intel_bufmgr *bufmgr, int enable)
309720131375Smrg{
3098fe517fc9Smrg	fprintf(stderr, "libdrm aub dumping is deprecated.\n\n"
3099fe517fc9Smrg		"Use intel_aubdump from intel-gpu-tools instead.  Install intel-gpu-tools,\n"
3100fe517fc9Smrg		"then run (for example)\n\n"
3101fe517fc9Smrg		"\t$ intel_aubdump --output=trace.aub glxgears -geometry 500x500\n\n"
3102fe517fc9Smrg		"See the intel_aubdump man page for more details.\n");
310320131375Smrg}
310420131375Smrg
3105424e9256Smrgdrm_intel_context *
310620131375Smrgdrm_intel_gem_context_create(drm_intel_bufmgr *bufmgr)
310720131375Smrg{
310820131375Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
310920131375Smrg	struct drm_i915_gem_context_create create;
311020131375Smrg	drm_intel_context *context = NULL;
311120131375Smrg	int ret;
311220131375Smrg
311320131375Smrg	context = calloc(1, sizeof(*context));
311420131375Smrg	if (!context)
311520131375Smrg		return NULL;
311620131375Smrg
3117424e9256Smrg	memclear(create);
311820131375Smrg	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_CONTEXT_CREATE, &create);
311920131375Smrg	if (ret != 0) {
312020131375Smrg		DBG("DRM_IOCTL_I915_GEM_CONTEXT_CREATE failed: %s\n",
312120131375Smrg		    strerror(errno));
312220131375Smrg		free(context);
312320131375Smrg		return NULL;
312420131375Smrg	}
312520131375Smrg
312620131375Smrg	context->ctx_id = create.ctx_id;
312720131375Smrg	context->bufmgr = bufmgr;
312820131375Smrg
312920131375Smrg	return context;
313020131375Smrg}
313120131375Smrg
3132424e9256Smrgvoid
313320131375Smrgdrm_intel_gem_context_destroy(drm_intel_context *ctx)
313420131375Smrg{
313520131375Smrg	drm_intel_bufmgr_gem *bufmgr_gem;
313620131375Smrg	struct drm_i915_gem_context_destroy destroy;
313720131375Smrg	int ret;
313820131375Smrg
313920131375Smrg	if (ctx == NULL)
314020131375Smrg		return;
314120131375Smrg
3142424e9256Smrg	memclear(destroy);
314320131375Smrg
314420131375Smrg	bufmgr_gem = (drm_intel_bufmgr_gem *)ctx->bufmgr;
314520131375Smrg	destroy.ctx_id = ctx->ctx_id;
314620131375Smrg	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_CONTEXT_DESTROY,
314720131375Smrg		       &destroy);
314820131375Smrg	if (ret != 0)
314920131375Smrg		fprintf(stderr, "DRM_IOCTL_I915_GEM_CONTEXT_DESTROY failed: %s\n",
315020131375Smrg			strerror(errno));
315120131375Smrg
315220131375Smrg	free(ctx);
315320131375Smrg}
315420131375Smrg
3155424e9256Smrgint
315620131375Smrgdrm_intel_get_reset_stats(drm_intel_context *ctx,
315720131375Smrg			  uint32_t *reset_count,
315820131375Smrg			  uint32_t *active,
315920131375Smrg			  uint32_t *pending)
316020131375Smrg{
316120131375Smrg	drm_intel_bufmgr_gem *bufmgr_gem;
316220131375Smrg	struct drm_i915_reset_stats stats;
316320131375Smrg	int ret;
316420131375Smrg
316520131375Smrg	if (ctx == NULL)
316620131375Smrg		return -EINVAL;
316720131375Smrg
3168424e9256Smrg	memclear(stats);
316920131375Smrg
317020131375Smrg	bufmgr_gem = (drm_intel_bufmgr_gem *)ctx->bufmgr;
317120131375Smrg	stats.ctx_id = ctx->ctx_id;
317220131375Smrg	ret = drmIoctl(bufmgr_gem->fd,
317320131375Smrg		       DRM_IOCTL_I915_GET_RESET_STATS,
317420131375Smrg		       &stats);
317520131375Smrg	if (ret == 0) {
317620131375Smrg		if (reset_count != NULL)
317720131375Smrg			*reset_count = stats.reset_count;
317820131375Smrg
317920131375Smrg		if (active != NULL)
318020131375Smrg			*active = stats.batch_active;
318120131375Smrg
318220131375Smrg		if (pending != NULL)
318320131375Smrg			*pending = stats.batch_pending;
318420131375Smrg	}
318520131375Smrg
318620131375Smrg	return ret;
318720131375Smrg}
318820131375Smrg
3189424e9256Smrgint
319020131375Smrgdrm_intel_reg_read(drm_intel_bufmgr *bufmgr,
319120131375Smrg		   uint32_t offset,
319220131375Smrg		   uint64_t *result)
319320131375Smrg{
319420131375Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
319520131375Smrg	struct drm_i915_reg_read reg_read;
319620131375Smrg	int ret;
319720131375Smrg
3198424e9256Smrg	memclear(reg_read);
319920131375Smrg	reg_read.offset = offset;
320020131375Smrg
320120131375Smrg	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_REG_READ, &reg_read);
320220131375Smrg
320320131375Smrg	*result = reg_read.val;
320420131375Smrg	return ret;
320520131375Smrg}
320620131375Smrg
3207424e9256Smrgint
3208424e9256Smrgdrm_intel_get_subslice_total(int fd, unsigned int *subslice_total)
3209424e9256Smrg{
3210424e9256Smrg	drm_i915_getparam_t gp;
3211424e9256Smrg	int ret;
3212424e9256Smrg
3213424e9256Smrg	memclear(gp);
3214424e9256Smrg	gp.value = (int*)subslice_total;
3215424e9256Smrg	gp.param = I915_PARAM_SUBSLICE_TOTAL;
3216424e9256Smrg	ret = drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
3217424e9256Smrg	if (ret)
3218424e9256Smrg		return -errno;
3219424e9256Smrg
3220424e9256Smrg	return 0;
3221424e9256Smrg}
3222424e9256Smrg
3223424e9256Smrgint
3224424e9256Smrgdrm_intel_get_eu_total(int fd, unsigned int *eu_total)
3225424e9256Smrg{
3226424e9256Smrg	drm_i915_getparam_t gp;
3227424e9256Smrg	int ret;
3228424e9256Smrg
3229424e9256Smrg	memclear(gp);
3230424e9256Smrg	gp.value = (int*)eu_total;
3231424e9256Smrg	gp.param = I915_PARAM_EU_TOTAL;
3232424e9256Smrg	ret = drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
3233424e9256Smrg	if (ret)
3234424e9256Smrg		return -errno;
3235424e9256Smrg
3236424e9256Smrg	return 0;
3237424e9256Smrg}
323820131375Smrg
323920131375Smrg/**
324020131375Smrg * Annotate the given bo for use in aub dumping.
324120131375Smrg *
324220131375Smrg * \param annotations is an array of drm_intel_aub_annotation objects
324320131375Smrg * describing the type of data in various sections of the bo.  Each
324420131375Smrg * element of the array specifies the type and subtype of a section of
324520131375Smrg * the bo, and the past-the-end offset of that section.  The elements
324620131375Smrg * of \c annotations must be sorted so that ending_offset is
324720131375Smrg * increasing.
324820131375Smrg *
324920131375Smrg * \param count is the number of elements in the \c annotations array.
325020131375Smrg * If \c count is zero, then \c annotations will not be dereferenced.
325120131375Smrg *
325220131375Smrg * Annotations are copied into a private data structure, so caller may
325320131375Smrg * re-use the memory pointed to by \c annotations after the call
325420131375Smrg * returns.
325520131375Smrg *
325620131375Smrg * Annotations are stored for the lifetime of the bo; to reset to the
325720131375Smrg * default state (no annotations), call this function with a \c count
325820131375Smrg * of zero.
325920131375Smrg */
3260424e9256Smrgvoid
326120131375Smrgdrm_intel_bufmgr_gem_set_aub_annotations(drm_intel_bo *bo,
326220131375Smrg					 drm_intel_aub_annotation *annotations,
326320131375Smrg					 unsigned count)
326420131375Smrg{
326520131375Smrg}
326620131375Smrg
3267a884aba1Smrgstatic pthread_mutex_t bufmgr_list_mutex = PTHREAD_MUTEX_INITIALIZER;
3268a884aba1Smrgstatic drmMMListHead bufmgr_list = { &bufmgr_list, &bufmgr_list };
3269a884aba1Smrg
3270a884aba1Smrgstatic drm_intel_bufmgr_gem *
3271a884aba1Smrgdrm_intel_bufmgr_gem_find(int fd)
3272a884aba1Smrg{
3273a884aba1Smrg	drm_intel_bufmgr_gem *bufmgr_gem;
3274a884aba1Smrg
3275a884aba1Smrg	DRMLISTFOREACHENTRY(bufmgr_gem, &bufmgr_list, managers) {
3276a884aba1Smrg		if (bufmgr_gem->fd == fd) {
3277a884aba1Smrg			atomic_inc(&bufmgr_gem->refcount);
3278a884aba1Smrg			return bufmgr_gem;
3279a884aba1Smrg		}
3280a884aba1Smrg	}
3281a884aba1Smrg
3282a884aba1Smrg	return NULL;
3283a884aba1Smrg}
3284a884aba1Smrg
3285a884aba1Smrgstatic void
3286a884aba1Smrgdrm_intel_bufmgr_gem_unref(drm_intel_bufmgr *bufmgr)
3287a884aba1Smrg{
3288a884aba1Smrg	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
3289a884aba1Smrg
3290a884aba1Smrg	if (atomic_add_unless(&bufmgr_gem->refcount, -1, 1)) {
3291a884aba1Smrg		pthread_mutex_lock(&bufmgr_list_mutex);
3292a884aba1Smrg
3293a884aba1Smrg		if (atomic_dec_and_test(&bufmgr_gem->refcount)) {
3294a884aba1Smrg			DRMLISTDEL(&bufmgr_gem->managers);
3295a884aba1Smrg			drm_intel_bufmgr_gem_destroy(bufmgr);
3296a884aba1Smrg		}
3297a884aba1Smrg
3298a884aba1Smrg		pthread_mutex_unlock(&bufmgr_list_mutex);
3299a884aba1Smrg	}
3300a884aba1Smrg}
3301a884aba1Smrg
330222944501Smrg/**
330322944501Smrg * Initializes the GEM buffer manager, which uses the kernel to allocate, map,
330422944501Smrg * and manage map buffer objections.
330522944501Smrg *
330622944501Smrg * \param fd File descriptor of the opened DRM device.
330722944501Smrg */
3308424e9256Smrgdrm_intel_bufmgr *
330922944501Smrgdrm_intel_bufmgr_gem_init(int fd, int batch_size)
331022944501Smrg{
331122944501Smrg	drm_intel_bufmgr_gem *bufmgr_gem;
331222944501Smrg	struct drm_i915_gem_get_aperture aperture;
331322944501Smrg	drm_i915_getparam_t gp;
331420131375Smrg	int ret, tmp;
331520131375Smrg	bool exec2 = false;
331622944501Smrg
3317a884aba1Smrg	pthread_mutex_lock(&bufmgr_list_mutex);
3318a884aba1Smrg
3319a884aba1Smrg	bufmgr_gem = drm_intel_bufmgr_gem_find(fd);
3320a884aba1Smrg	if (bufmgr_gem)
3321a884aba1Smrg		goto exit;
3322a884aba1Smrg
332322944501Smrg	bufmgr_gem = calloc(1, sizeof(*bufmgr_gem));
332422944501Smrg	if (bufmgr_gem == NULL)
3325a884aba1Smrg		goto exit;
332622944501Smrg
332722944501Smrg	bufmgr_gem->fd = fd;
3328a884aba1Smrg	atomic_set(&bufmgr_gem->refcount, 1);
332922944501Smrg
333022944501Smrg	if (pthread_mutex_init(&bufmgr_gem->lock, NULL) != 0) {
333122944501Smrg		free(bufmgr_gem);
3332a884aba1Smrg		bufmgr_gem = NULL;
3333a884aba1Smrg		goto exit;
333422944501Smrg	}
333522944501Smrg
3336424e9256Smrg	memclear(aperture);
33376d98c517Smrg	ret = drmIoctl(bufmgr_gem->fd,
33386d98c517Smrg		       DRM_IOCTL_I915_GEM_GET_APERTURE,
33396d98c517Smrg		       &aperture);
334022944501Smrg
334122944501Smrg	if (ret == 0)
334222944501Smrg		bufmgr_gem->gtt_size = aperture.aper_available_size;
334322944501Smrg	else {
334422944501Smrg		fprintf(stderr, "DRM_IOCTL_I915_GEM_APERTURE failed: %s\n",
334522944501Smrg			strerror(errno));
334622944501Smrg		bufmgr_gem->gtt_size = 128 * 1024 * 1024;
334722944501Smrg		fprintf(stderr, "Assuming %dkB available aperture size.\n"
334822944501Smrg			"May lead to reduced performance or incorrect "
334922944501Smrg			"rendering.\n",
335022944501Smrg			(int)bufmgr_gem->gtt_size / 1024);
335122944501Smrg	}
335222944501Smrg
335320131375Smrg	bufmgr_gem->pci_device = get_pci_device_id(bufmgr_gem);
335422944501Smrg
335520131375Smrg	if (IS_GEN2(bufmgr_gem->pci_device))
335622944501Smrg		bufmgr_gem->gen = 2;
335720131375Smrg	else if (IS_GEN3(bufmgr_gem->pci_device))
335822944501Smrg		bufmgr_gem->gen = 3;
335920131375Smrg	else if (IS_GEN4(bufmgr_gem->pci_device))
336022944501Smrg		bufmgr_gem->gen = 4;
336120131375Smrg	else if (IS_GEN5(bufmgr_gem->pci_device))
336220131375Smrg		bufmgr_gem->gen = 5;
336320131375Smrg	else if (IS_GEN6(bufmgr_gem->pci_device))
336422944501Smrg		bufmgr_gem->gen = 6;
336520131375Smrg	else if (IS_GEN7(bufmgr_gem->pci_device))
336620131375Smrg		bufmgr_gem->gen = 7;
336720131375Smrg	else if (IS_GEN8(bufmgr_gem->pci_device))
336820131375Smrg		bufmgr_gem->gen = 8;
33693c748557Ssnj	else if (IS_GEN9(bufmgr_gem->pci_device))
33703c748557Ssnj		bufmgr_gem->gen = 9;
337120131375Smrg	else {
337220131375Smrg		free(bufmgr_gem);
3373a884aba1Smrg		bufmgr_gem = NULL;
3374a884aba1Smrg		goto exit;
337520131375Smrg	}
337620131375Smrg
337720131375Smrg	if (IS_GEN3(bufmgr_gem->pci_device) &&
337820131375Smrg	    bufmgr_gem->gtt_size > 256*1024*1024) {
337920131375Smrg		/* The unmappable part of gtt on gen 3 (i.e. above 256MB) can't
338020131375Smrg		 * be used for tiled blits. To simplify the accounting, just
3381fe517fc9Smrg		 * subtract the unmappable part (fixed to 256MB on all known
338220131375Smrg		 * gen3 devices) if the kernel advertises it. */
338320131375Smrg		bufmgr_gem->gtt_size -= 256*1024*1024;
338420131375Smrg	}
338520131375Smrg
3386424e9256Smrg	memclear(gp);
338720131375Smrg	gp.value = &tmp;
338822944501Smrg
338922944501Smrg	gp.param = I915_PARAM_HAS_EXECBUF2;
33906d98c517Smrg	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
339122944501Smrg	if (!ret)
339220131375Smrg		exec2 = true;
339322944501Smrg
3394aaba2545Smrg	gp.param = I915_PARAM_HAS_BSD;
33956d98c517Smrg	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
33969ce4edccSmrg	bufmgr_gem->has_bsd = ret == 0;
33979ce4edccSmrg
33989ce4edccSmrg	gp.param = I915_PARAM_HAS_BLT;
33999ce4edccSmrg	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
34009ce4edccSmrg	bufmgr_gem->has_blt = ret == 0;
34019ce4edccSmrg
34029ce4edccSmrg	gp.param = I915_PARAM_HAS_RELAXED_FENCING;
34039ce4edccSmrg	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
34049ce4edccSmrg	bufmgr_gem->has_relaxed_fencing = ret == 0;
3405aaba2545Smrg
3406424e9256Smrg	bufmgr_gem->bufmgr.bo_alloc_userptr = check_bo_alloc_userptr;
3407a884aba1Smrg
340820131375Smrg	gp.param = I915_PARAM_HAS_WAIT_TIMEOUT;
340920131375Smrg	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
341020131375Smrg	bufmgr_gem->has_wait_timeout = ret == 0;
341120131375Smrg
341220131375Smrg	gp.param = I915_PARAM_HAS_LLC;
341320131375Smrg	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
341420131375Smrg	if (ret != 0) {
341520131375Smrg		/* Kernel does not supports HAS_LLC query, fallback to GPU
341620131375Smrg		 * generation detection and assume that we have LLC on GEN6/7
341720131375Smrg		 */
341820131375Smrg		bufmgr_gem->has_llc = (IS_GEN6(bufmgr_gem->pci_device) |
341920131375Smrg				IS_GEN7(bufmgr_gem->pci_device));
342020131375Smrg	} else
342120131375Smrg		bufmgr_gem->has_llc = *gp.value;
342220131375Smrg
342320131375Smrg	gp.param = I915_PARAM_HAS_VEBOX;
342420131375Smrg	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
342520131375Smrg	bufmgr_gem->has_vebox = (ret == 0) & (*gp.value > 0);
342620131375Smrg
3427fe517fc9Smrg	gp.param = I915_PARAM_HAS_EXEC_SOFTPIN;
3428fe517fc9Smrg	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
3429fe517fc9Smrg	if (ret == 0 && *gp.value > 0)
3430fe517fc9Smrg		bufmgr_gem->bufmgr.bo_set_softpin_offset = drm_intel_gem_bo_set_softpin_offset;
3431fe517fc9Smrg
343222944501Smrg	if (bufmgr_gem->gen < 4) {
343322944501Smrg		gp.param = I915_PARAM_NUM_FENCES_AVAIL;
343422944501Smrg		gp.value = &bufmgr_gem->available_fences;
34356d98c517Smrg		ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
343622944501Smrg		if (ret) {
343722944501Smrg			fprintf(stderr, "get fences failed: %d [%d]\n", ret,
343822944501Smrg				errno);
343922944501Smrg			fprintf(stderr, "param: %d, val: %d\n", gp.param,
344022944501Smrg				*gp.value);
344122944501Smrg			bufmgr_gem->available_fences = 0;
344222944501Smrg		} else {
344322944501Smrg			/* XXX The kernel reports the total number of fences,
344422944501Smrg			 * including any that may be pinned.
344522944501Smrg			 *
344622944501Smrg			 * We presume that there will be at least one pinned
344722944501Smrg			 * fence for the scanout buffer, but there may be more
344822944501Smrg			 * than one scanout and the user may be manually
344922944501Smrg			 * pinning buffers. Let's move to execbuffer2 and
345022944501Smrg			 * thereby forget the insanity of using fences...
345122944501Smrg			 */
345222944501Smrg			bufmgr_gem->available_fences -= 2;
345322944501Smrg			if (bufmgr_gem->available_fences < 0)
345422944501Smrg				bufmgr_gem->available_fences = 0;
345522944501Smrg		}
345622944501Smrg	}
345722944501Smrg
3458fe517fc9Smrg	if (bufmgr_gem->gen >= 8) {
3459fe517fc9Smrg		gp.param = I915_PARAM_HAS_ALIASING_PPGTT;
3460fe517fc9Smrg		ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
3461fe517fc9Smrg		if (ret == 0 && *gp.value == 3)
3462fe517fc9Smrg			bufmgr_gem->bufmgr.bo_use_48b_address_range = drm_intel_gem_bo_use_48b_address_range;
3463fe517fc9Smrg	}
3464fe517fc9Smrg
346522944501Smrg	/* Let's go with one relocation per every 2 dwords (but round down a bit
346622944501Smrg	 * since a power of two will mean an extra page allocation for the reloc
346722944501Smrg	 * buffer).
346822944501Smrg	 *
346922944501Smrg	 * Every 4 was too few for the blender benchmark.
347022944501Smrg	 */
347122944501Smrg	bufmgr_gem->max_relocs = batch_size / sizeof(uint32_t) / 2 - 2;
347222944501Smrg
347322944501Smrg	bufmgr_gem->bufmgr.bo_alloc = drm_intel_gem_bo_alloc;
347422944501Smrg	bufmgr_gem->bufmgr.bo_alloc_for_render =
347522944501Smrg	    drm_intel_gem_bo_alloc_for_render;
347622944501Smrg	bufmgr_gem->bufmgr.bo_alloc_tiled = drm_intel_gem_bo_alloc_tiled;
347722944501Smrg	bufmgr_gem->bufmgr.bo_reference = drm_intel_gem_bo_reference;
347822944501Smrg	bufmgr_gem->bufmgr.bo_unreference = drm_intel_gem_bo_unreference;
347922944501Smrg	bufmgr_gem->bufmgr.bo_map = drm_intel_gem_bo_map;
348022944501Smrg	bufmgr_gem->bufmgr.bo_unmap = drm_intel_gem_bo_unmap;
348122944501Smrg	bufmgr_gem->bufmgr.bo_subdata = drm_intel_gem_bo_subdata;
348222944501Smrg	bufmgr_gem->bufmgr.bo_get_subdata = drm_intel_gem_bo_get_subdata;
348322944501Smrg	bufmgr_gem->bufmgr.bo_wait_rendering = drm_intel_gem_bo_wait_rendering;
348422944501Smrg	bufmgr_gem->bufmgr.bo_emit_reloc = drm_intel_gem_bo_emit_reloc;
348522944501Smrg	bufmgr_gem->bufmgr.bo_emit_reloc_fence = drm_intel_gem_bo_emit_reloc_fence;
348622944501Smrg	bufmgr_gem->bufmgr.bo_pin = drm_intel_gem_bo_pin;
348722944501Smrg	bufmgr_gem->bufmgr.bo_unpin = drm_intel_gem_bo_unpin;
348822944501Smrg	bufmgr_gem->bufmgr.bo_get_tiling = drm_intel_gem_bo_get_tiling;
348922944501Smrg	bufmgr_gem->bufmgr.bo_set_tiling = drm_intel_gem_bo_set_tiling;
349022944501Smrg	bufmgr_gem->bufmgr.bo_flink = drm_intel_gem_bo_flink;
349122944501Smrg	/* Use the new one if available */
3492aaba2545Smrg	if (exec2) {
349322944501Smrg		bufmgr_gem->bufmgr.bo_exec = drm_intel_gem_bo_exec2;
34949ce4edccSmrg		bufmgr_gem->bufmgr.bo_mrb_exec = drm_intel_gem_bo_mrb_exec2;
3495aaba2545Smrg	} else
349622944501Smrg		bufmgr_gem->bufmgr.bo_exec = drm_intel_gem_bo_exec;
349722944501Smrg	bufmgr_gem->bufmgr.bo_busy = drm_intel_gem_bo_busy;
349822944501Smrg	bufmgr_gem->bufmgr.bo_madvise = drm_intel_gem_bo_madvise;
3499a884aba1Smrg	bufmgr_gem->bufmgr.destroy = drm_intel_bufmgr_gem_unref;
350022944501Smrg	bufmgr_gem->bufmgr.debug = 0;
350122944501Smrg	bufmgr_gem->bufmgr.check_aperture_space =
350222944501Smrg	    drm_intel_gem_check_aperture_space;
350322944501Smrg	bufmgr_gem->bufmgr.bo_disable_reuse = drm_intel_gem_bo_disable_reuse;
3504aaba2545Smrg	bufmgr_gem->bufmgr.bo_is_reusable = drm_intel_gem_bo_is_reusable;
350522944501Smrg	bufmgr_gem->bufmgr.get_pipe_from_crtc_id =
350622944501Smrg	    drm_intel_gem_get_pipe_from_crtc_id;
350722944501Smrg	bufmgr_gem->bufmgr.bo_references = drm_intel_gem_bo_references;
350822944501Smrg
350920131375Smrg	DRMINITLISTHEAD(&bufmgr_gem->named);
3510aaba2545Smrg	init_cache_buckets(bufmgr_gem);
351122944501Smrg
351220131375Smrg	DRMINITLISTHEAD(&bufmgr_gem->vma_cache);
351320131375Smrg	bufmgr_gem->vma_max = -1; /* unlimited by default */
351420131375Smrg
3515a884aba1Smrg	DRMLISTADD(&bufmgr_gem->managers, &bufmgr_list);
3516a884aba1Smrg
3517a884aba1Smrgexit:
3518a884aba1Smrg	pthread_mutex_unlock(&bufmgr_list_mutex);
3519a884aba1Smrg
3520a884aba1Smrg	return bufmgr_gem != NULL ? &bufmgr_gem->bufmgr : NULL;
352122944501Smrg}
3522