intel_batchbuffer.h 10.4 KB
Newer Older
1 2 3
#ifndef INTEL_BATCHBUFFER_H
#define INTEL_BATCHBUFFER_H

4
#include <stdint.h>
5
#include <intel_bufmgr.h>
6 7
#include <i915_drm.h>

8
#include "igt_core.h"
9
#include "intel_reg.h"
10 11 12 13

#define BATCH_SZ 4096
#define BATCH_RESERVED 16

14
struct intel_batchbuffer {
15
	drm_intel_bufmgr *bufmgr;
16
	uint32_t devid;
17
	int gen;
18

19
	drm_intel_context *ctx;
20 21
	drm_intel_bo *bo;

22
	uint8_t buffer[BATCH_SZ];
23
	uint8_t *ptr, *end;
24 25
};

26 27
struct intel_batchbuffer *intel_batchbuffer_alloc(drm_intel_bufmgr *bufmgr,
						  uint32_t devid);
28

29 30 31 32
void intel_batchbuffer_set_context(struct intel_batchbuffer *batch,
				   drm_intel_context *ctx);


33 34 35 36
void intel_batchbuffer_free(struct intel_batchbuffer *batch);


void intel_batchbuffer_flush(struct intel_batchbuffer *batch);
37
void intel_batchbuffer_flush_on_ring(struct intel_batchbuffer *batch, int ring);
Ben Widawsky's avatar
Ben Widawsky committed
38 39
void intel_batchbuffer_flush_with_context(struct intel_batchbuffer *batch,
					  drm_intel_context *context);
40 41 42

void intel_batchbuffer_reset(struct intel_batchbuffer *batch);

43 44 45
uint32_t intel_batchbuffer_copy_data(struct intel_batchbuffer *batch,
				const void *data, unsigned int bytes,
				uint32_t align);
46 47 48

void intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
				  drm_intel_bo *buffer,
49
				  uint64_t delta,
50
				  uint32_t read_domains,
Daniel Vetter's avatar
Daniel Vetter committed
51 52
				  uint32_t write_domain,
				  int fenced);
53

54 55 56 57 58 59 60 61 62 63
uint32_t
intel_batchbuffer_align(struct intel_batchbuffer *batch, uint32_t align);

void *
intel_batchbuffer_subdata_alloc(struct intel_batchbuffer *batch,
				uint32_t size, uint32_t align);

uint32_t
intel_batchbuffer_subdata_offset(struct intel_batchbuffer *batch, void *ptr);

64 65 66 67 68
/* Inline functions - might actually be better off with these
 * non-inlined.  Certainly better off switching all command packets to
 * be passed as structs rather than dwords, but that's a little bit of
 * work...
 */
Ben Widawsky's avatar
Ben Widawsky committed
69
#pragma GCC diagnostic ignored "-Winline"
70
static inline unsigned int
71 72
intel_batchbuffer_space(struct intel_batchbuffer *batch)
{
73
	return (BATCH_SZ - BATCH_RESERVED) - (batch->ptr - batch->buffer);
74 75 76 77 78 79
}


static inline void
intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, uint32_t dword)
{
80
	igt_assert(intel_batchbuffer_space(batch) >= 4);
81 82 83 84 85 86 87 88
	*(uint32_t *) (batch->ptr) = dword;
	batch->ptr += 4;
}

static inline void
intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
                                unsigned int sz)
{
89
	igt_assert(sz < BATCH_SZ - BATCH_RESERVED);
90 91 92 93
	if (intel_batchbuffer_space(batch) < sz)
		intel_batchbuffer_flush(batch);
}

94 95 96
/**
 * BEGIN_BATCH:
 * @n: number of DWORDS to emit
97
 * @r: number of RELOCS to emit
98 99 100 101 102 103 104
 *
 * Prepares a batch to emit @n DWORDS, flushing it if there's not enough space
 * available.
 *
 * This macro needs a pointer to an #intel_batchbuffer structure called batch in
 * scope.
 */
105 106
#define BEGIN_BATCH(n, r) do {						\
	int __n = (n); \
107
	igt_assert(batch->end == NULL); \
108 109 110 111
	if (batch->gen >= 8) __n += r;	\
	__n *= 4; \
	intel_batchbuffer_require_space(batch, __n);			\
	batch->end = batch->ptr + __n; \
112 113
} while (0)

114 115 116 117 118 119 120 121 122
/**
 * OUT_BATCH:
 * @d: DWORD to emit
 *
 * Emits @d into a batch.
 *
 * This macro needs a pointer to an #intel_batchbuffer structure called batch in
 * scope.
 */
123 124
#define OUT_BATCH(d) intel_batchbuffer_emit_dword(batch, d)

125 126 127 128 129 130 131 132 133 134 135 136
/**
 * OUT_RELOC_FENCED:
 * @buf: relocation target libdrm buffer object
 * @read_domains: gem domain bits for the relocation
 * @write_domain: gem domain bit for the relocation
 * @delta: delta value to add to @buffer's gpu address
 *
 * Emits a fenced relocation into a batch.
 *
 * This macro needs a pointer to an #intel_batchbuffer structure called batch in
 * scope.
 */
Daniel Vetter's avatar
Daniel Vetter committed
137
#define OUT_RELOC_FENCED(buf, read_domains, write_domain, delta) do {		\
138
	igt_assert((delta) >= 0);						\
Daniel Vetter's avatar
Daniel Vetter committed
139 140 141 142
	intel_batchbuffer_emit_reloc(batch, buf, delta,			\
				     read_domains, write_domain, 1);	\
} while (0)

143
/**
144
 * OUT_RELOC:
145 146 147 148 149 150 151 152 153 154
 * @buf: relocation target libdrm buffer object
 * @read_domains: gem domain bits for the relocation
 * @write_domain: gem domain bit for the relocation
 * @delta: delta value to add to @buffer's gpu address
 *
 * Emits a normal, unfenced relocation into a batch.
 *
 * This macro needs a pointer to an #intel_batchbuffer structure called batch in
 * scope.
 */
155
#define OUT_RELOC(buf, read_domains, write_domain, delta) do {		\
156
	igt_assert((delta) >= 0);						\
157
	intel_batchbuffer_emit_reloc(batch, buf, delta,			\
Daniel Vetter's avatar
Daniel Vetter committed
158
				     read_domains, write_domain, 0);	\
159 160
} while (0)

161 162 163 164 165 166 167 168
/**
 * ADVANCE_BATCH:
 *
 * Completes the batch command emission sequence started with #BEGIN_BATCH.
 *
 * This macro needs a pointer to an #intel_batchbuffer structure called batch in
 * scope.
 */
169
#define ADVANCE_BATCH() do {						\
170 171
	igt_assert(batch->ptr == batch->end); \
	batch->end = NULL; \
172 173
} while(0)

174 175 176 177 178 179
#define BLIT_COPY_BATCH_START(flags) do { \
	BEGIN_BATCH(8, 2); \
	OUT_BATCH(XY_SRC_COPY_BLT_CMD | \
		  XY_SRC_COPY_BLT_WRITE_ALPHA | \
		  XY_SRC_COPY_BLT_WRITE_RGB | \
		  (flags) | \
180
		  (6 + 2*(batch->gen >= 8))); \
181 182
} while(0)

183 184 185 186 187
#define COLOR_BLIT_COPY_BATCH_START(flags) do { \
	BEGIN_BATCH(6, 1); \
	OUT_BATCH(XY_COLOR_BLT_CMD_NOLEN | \
		  COLOR_BLT_WRITE_ALPHA | \
		  XY_COLOR_BLT_WRITE_RGB | \
188
		  (flags) | \
189
		  (4 + (batch->gen >= 8))); \
190 191
} while(0)

192 193 194 195 196
void
intel_blt_copy(struct intel_batchbuffer *batch,
	      drm_intel_bo *src_bo, int src_x1, int src_y1, int src_pitch,
	      drm_intel_bo *dst_bo, int dst_x1, int dst_y1, int dst_pitch,
	      int width, int height, int bpp);
197 198
void intel_copy_bo(struct intel_batchbuffer *batch,
		   drm_intel_bo *dst_bo, drm_intel_bo *src_bo,
199
		   long int size);
200

201
/*
202 203 204 205 206 207 208 209 210 211 212
 * Yf/Ys tiling
 *
 * Tiling mode in the I915_TILING_... namespace for new tiling modes which are
 * defined in the kernel. (They are not fenceable so the kernel does not need
 * to know about them.)
 *
 * They are to be used the the blitting routines below.
 */
#define I915_TILING_Yf	3
#define I915_TILING_Ys	4

213 214 215 216 217
/**
 * igt_buf:
 * @bo: underlying libdrm buffer object
 * @stride: stride of the buffer
 * @tiling: tiling mode bits
218
 * @bpp: bits per pixel, 8, 16 or 32.
219 220 221 222 223
 * @data: pointer to the memory mapping of the buffer
 * @size: size of the buffer object
 *
 * This is a i-g-t buffer object wrapper structure which augments the baseline
 * libdrm buffer object with suitable data needed by the render copy and the
224
 * fill functions.
225
 */
226
struct igt_buf {
227 228 229
	drm_intel_bo *bo;
	uint32_t stride;
	uint32_t tiling;
230
	uint32_t bpp;
231 232 233 234 235 236 237 238
	uint32_t *data;
	uint32_t size;
	struct {
		uint32_t offset;
		uint32_t stride;
	} aux;
	/*< private >*/
	unsigned num_tiles;
239 240
};

Ville Syrjälä's avatar
Ville Syrjälä committed
241 242
unsigned igt_buf_width(const struct igt_buf *buf);
unsigned igt_buf_height(const struct igt_buf *buf);
243

244
void igt_blitter_fast_copy(struct intel_batchbuffer *batch,
Ville Syrjälä's avatar
Ville Syrjälä committed
245
			   const struct igt_buf *src, unsigned src_delta,
246 247 248
			   unsigned src_x, unsigned src_y,
			   unsigned width, unsigned height,
			   int bpp,
Ville Syrjälä's avatar
Ville Syrjälä committed
249
			   const struct igt_buf *dst, unsigned dst_delta,
250
			   unsigned dst_x, unsigned dst_y);
251

252 253 254
void igt_blitter_fast_copy__raw(int fd,
				/* src */
				uint32_t src_handle,
255
				unsigned int src_delta,
256 257 258 259 260 261 262
				unsigned int src_stride,
				unsigned int src_tiling,
				unsigned int src_x, unsigned src_y,

				/* size */
				unsigned int width, unsigned int height,

263 264 265
				/* bpp */
				int bpp,

266 267
				/* dst */
				uint32_t dst_handle,
268
				unsigned int dst_delta,
269 270 271 272
				unsigned int dst_stride,
				unsigned int dst_tiling,
				unsigned int dst_x, unsigned dst_y);

273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
/**
 * igt_render_copyfunc_t:
 * @batch: batchbuffer object
 * @context: libdrm hardware context to use
 * @src: source i-g-t buffer object
 * @src_x: source pixel x-coordination
 * @src_y: source pixel y-coordination
 * @width: width of the copied rectangle
 * @height: height of the copied rectangle
 * @dst: destination i-g-t buffer object
 * @dst_x: destination pixel x-coordination
 * @dst_y: destination pixel y-coordination
 *
 * This is the type of the per-platform render copy functions. The
 * platform-specific implementation can be obtained by calling
 * igt_get_render_copyfunc().
 *
 * A render copy function will emit a batchbuffer to the kernel which executes
 * the specified blit copy operation using the render engine. @context is
 * optional and can be NULL.
 */
294 295
typedef void (*igt_render_copyfunc_t)(struct intel_batchbuffer *batch,
				      drm_intel_context *context,
Ville Syrjälä's avatar
Ville Syrjälä committed
296
				      const struct igt_buf *src, unsigned src_x, unsigned src_y,
297
				      unsigned width, unsigned height,
Ville Syrjälä's avatar
Ville Syrjälä committed
298
				      const struct igt_buf *dst, unsigned dst_x, unsigned dst_y);
299

300
igt_render_copyfunc_t igt_get_render_copyfunc(int devid);
301

302
/**
303
 * igt_fillfunc_t:
304 305 306 307 308 309 310 311
 * @batch: batchbuffer object
 * @dst: destination i-g-t buffer object
 * @x: destination pixel x-coordination
 * @y: destination pixel y-coordination
 * @width: width of the filled rectangle
 * @height: height of the filled rectangle
 * @color: fill color to use
 *
312
 * This is the type of the per-platform fill functions using media
Zhenyu Wang's avatar
Zhenyu Wang committed
313 314
 * or gpgpu pipeline. The platform-specific implementation can be obtained
 * by calling igt_get_media_fillfunc() or igt_get_gpgpu_fillfunc().
315
 *
316
 * A fill function will emit a batchbuffer to the kernel which executes
Zhenyu Wang's avatar
Zhenyu Wang committed
317
 * the specified blit fill operation using the media/gpgpu engine.
318
 */
319
typedef void (*igt_fillfunc_t)(struct intel_batchbuffer *batch,
Ville Syrjälä's avatar
Ville Syrjälä committed
320
			       const struct igt_buf *dst,
321 322 323
			       unsigned x, unsigned y,
			       unsigned width, unsigned height,
			       uint8_t color);
324

325
igt_fillfunc_t igt_get_media_fillfunc(int devid);
Zhenyu Wang's avatar
Zhenyu Wang committed
326
igt_fillfunc_t igt_get_gpgpu_fillfunc(int devid);
327

328 329 330 331 332 333 334
typedef void (*igt_vme_func_t)(struct intel_batchbuffer *batch,
			       const struct igt_buf *src,
			       unsigned int width, unsigned int height,
			       const struct igt_buf *dst);

igt_vme_func_t igt_get_media_vme_func(int devid);

Jeff McGee's avatar
Jeff McGee committed
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
/**
 * igt_media_spinfunc_t:
 * @batch: batchbuffer object
 * @dst: destination i-g-t buffer object
 * @spins: number of loops to execute
 *
 * This is the type of the per-platform media spin functions. The
 * platform-specific implementation can be obtained by calling
 * igt_get_media_spinfunc().
 *
 * The media spin function emits a batchbuffer for the render engine with
 * the media pipeline selected. The workload consists of a single thread
 * which spins in a tight loop the requested number of times. Each spin
 * increments a counter whose final 32-bit value is written to the
 * destination buffer on completion. This utility provides a simple way
 * to keep the render engine busy for a set time for various tests.
 */
typedef void (*igt_media_spinfunc_t)(struct intel_batchbuffer *batch,
Ville Syrjälä's avatar
Ville Syrjälä committed
353
				     const struct igt_buf *dst, uint32_t spins);
Jeff McGee's avatar
Jeff McGee committed
354 355 356

igt_media_spinfunc_t igt_get_media_spinfunc(int devid);

357
#endif