blob: 869747db064ee3cf131af7014b8fdb42fda68ed2 [file] [log] [blame]
Eric Anholt8c641832009-03-26 17:15:11 -07001#ifndef INTEL_BATCHBUFFER_H
2#define INTEL_BATCHBUFFER_H
3
Daniel Vetter7dc00012014-03-22 15:31:15 +01004#include <stdint.h>
Daniel Vetter924115b2014-03-22 20:18:51 +01005#include <intel_bufmgr.h>
Damien Lespiau672e88a2015-03-03 14:11:00 +00006#include <i915_drm.h>
7
Daniel Vetter0e22f142014-03-22 19:27:04 +01008#include "igt_core.h"
Daniel Vetter6cfcd712014-03-22 20:07:35 +01009#include "intel_reg.h"
Eric Anholt8c641832009-03-26 17:15:11 -070010
11#define BATCH_SZ 4096
12#define BATCH_RESERVED 16
13
Chris Wilson719ffef2011-05-22 10:34:12 +010014struct intel_batchbuffer {
Eric Anholt8c641832009-03-26 17:15:11 -070015 drm_intel_bufmgr *bufmgr;
Chris Wilsond4d769a2010-10-26 10:59:18 +010016 uint32_t devid;
Chris Wilson23d961e2014-08-29 14:49:59 +010017 int gen;
Eric Anholt8c641832009-03-26 17:15:11 -070018
Chris Wilson107151c2014-09-09 16:27:57 +010019 drm_intel_context *ctx;
Eric Anholt8c641832009-03-26 17:15:11 -070020 drm_intel_bo *bo;
21
Chris Wilson371f87f2011-02-01 10:53:57 +000022 uint8_t buffer[BATCH_SZ];
Chris Wilson982f7eb2014-08-29 15:19:57 +010023 uint8_t *ptr, *end;
Chris Wilson1945e2a2012-12-06 17:18:52 +000024 uint8_t *state;
Eric Anholt8c641832009-03-26 17:15:11 -070025};
26
Chris Wilsond4d769a2010-10-26 10:59:18 +010027struct intel_batchbuffer *intel_batchbuffer_alloc(drm_intel_bufmgr *bufmgr,
28 uint32_t devid);
Eric Anholt8c641832009-03-26 17:15:11 -070029
Chris Wilson107151c2014-09-09 16:27:57 +010030void intel_batchbuffer_set_context(struct intel_batchbuffer *batch,
31 drm_intel_context *ctx);
32
33
Eric Anholt8c641832009-03-26 17:15:11 -070034void intel_batchbuffer_free(struct intel_batchbuffer *batch);
35
36
37void intel_batchbuffer_flush(struct intel_batchbuffer *batch);
Daniel Vetterd42b7f92011-09-07 09:20:36 +020038void intel_batchbuffer_flush_on_ring(struct intel_batchbuffer *batch, int ring);
Ben Widawskya635a5a2012-01-15 14:52:33 -080039void intel_batchbuffer_flush_with_context(struct intel_batchbuffer *batch,
40 drm_intel_context *context);
Eric Anholt8c641832009-03-26 17:15:11 -070041
42void intel_batchbuffer_reset(struct intel_batchbuffer *batch);
43
44void intel_batchbuffer_data(struct intel_batchbuffer *batch,
45 const void *data, unsigned int bytes);
46
47void intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
48 drm_intel_bo *buffer,
Chris Wilson982f7eb2014-08-29 15:19:57 +010049 uint64_t delta,
Eric Anholt8c641832009-03-26 17:15:11 -070050 uint32_t read_domains,
Daniel Vetter8ab88c92011-03-27 16:17:54 +020051 uint32_t write_domain,
52 int fenced);
Eric Anholt8c641832009-03-26 17:15:11 -070053
54/* Inline functions - might actually be better off with these
55 * non-inlined. Certainly better off switching all command packets to
56 * be passed as structs rather than dwords, but that's a little bit of
57 * work...
58 */
Ben Widawsky802bd742012-01-15 13:41:42 -080059#pragma GCC diagnostic ignored "-Winline"
Oscar Mateo5032e7b2013-11-12 11:50:42 +000060static inline unsigned int
Eric Anholt8c641832009-03-26 17:15:11 -070061intel_batchbuffer_space(struct intel_batchbuffer *batch)
62{
Chris Wilson371f87f2011-02-01 10:53:57 +000063 return (BATCH_SZ - BATCH_RESERVED) - (batch->ptr - batch->buffer);
Eric Anholt8c641832009-03-26 17:15:11 -070064}
65
66
67static inline void
68intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, uint32_t dword)
69{
Daniel Vetter0e22f142014-03-22 19:27:04 +010070 igt_assert(intel_batchbuffer_space(batch) >= 4);
Eric Anholt8c641832009-03-26 17:15:11 -070071 *(uint32_t *) (batch->ptr) = dword;
72 batch->ptr += 4;
73}
74
75static inline void
76intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
77 unsigned int sz)
78{
Daniel Vetter0e22f142014-03-22 19:27:04 +010079 igt_assert(sz < BATCH_SZ - BATCH_RESERVED);
Eric Anholt8c641832009-03-26 17:15:11 -070080 if (intel_batchbuffer_space(batch) < sz)
81 intel_batchbuffer_flush(batch);
82}
83
Daniel Vetterec5f9e82014-03-13 01:13:28 +010084/**
85 * BEGIN_BATCH:
86 * @n: number of DWORDS to emit
Chris Wilson10552b52014-08-30 11:44:51 +010087 * @r: number of RELOCS to emit
Daniel Vetterec5f9e82014-03-13 01:13:28 +010088 *
89 * Prepares a batch to emit @n DWORDS, flushing it if there's not enough space
90 * available.
91 *
92 * This macro needs a pointer to an #intel_batchbuffer structure called batch in
93 * scope.
94 */
Chris Wilson10552b52014-08-30 11:44:51 +010095#define BEGIN_BATCH(n, r) do { \
96 int __n = (n); \
Chris Wilson982f7eb2014-08-29 15:19:57 +010097 igt_assert(batch->end == NULL); \
Chris Wilson10552b52014-08-30 11:44:51 +010098 if (batch->gen >= 8) __n += r; \
99 __n *= 4; \
100 intel_batchbuffer_require_space(batch, __n); \
101 batch->end = batch->ptr + __n; \
Eric Anholt8c641832009-03-26 17:15:11 -0700102} while (0)
103
Daniel Vetterec5f9e82014-03-13 01:13:28 +0100104/**
105 * OUT_BATCH:
106 * @d: DWORD to emit
107 *
108 * Emits @d into a batch.
109 *
110 * This macro needs a pointer to an #intel_batchbuffer structure called batch in
111 * scope.
112 */
Eric Anholt8c641832009-03-26 17:15:11 -0700113#define OUT_BATCH(d) intel_batchbuffer_emit_dword(batch, d)
114
Daniel Vetterec5f9e82014-03-13 01:13:28 +0100115/**
116 * OUT_RELOC_FENCED:
117 * @buf: relocation target libdrm buffer object
118 * @read_domains: gem domain bits for the relocation
119 * @write_domain: gem domain bit for the relocation
120 * @delta: delta value to add to @buffer's gpu address
121 *
122 * Emits a fenced relocation into a batch.
123 *
124 * This macro needs a pointer to an #intel_batchbuffer structure called batch in
125 * scope.
126 */
Daniel Vetter8ab88c92011-03-27 16:17:54 +0200127#define OUT_RELOC_FENCED(buf, read_domains, write_domain, delta) do { \
Daniel Vetter0e22f142014-03-22 19:27:04 +0100128 igt_assert((delta) >= 0); \
Daniel Vetter8ab88c92011-03-27 16:17:54 +0200129 intel_batchbuffer_emit_reloc(batch, buf, delta, \
130 read_domains, write_domain, 1); \
131} while (0)
132
Daniel Vetterec5f9e82014-03-13 01:13:28 +0100133/**
Mika Kuoppaladb259732014-03-26 17:24:43 +0200134 * OUT_RELOC:
Daniel Vetterec5f9e82014-03-13 01:13:28 +0100135 * @buf: relocation target libdrm buffer object
136 * @read_domains: gem domain bits for the relocation
137 * @write_domain: gem domain bit for the relocation
138 * @delta: delta value to add to @buffer's gpu address
139 *
140 * Emits a normal, unfenced relocation into a batch.
141 *
142 * This macro needs a pointer to an #intel_batchbuffer structure called batch in
143 * scope.
144 */
Eric Anholt8c641832009-03-26 17:15:11 -0700145#define OUT_RELOC(buf, read_domains, write_domain, delta) do { \
Daniel Vetter0e22f142014-03-22 19:27:04 +0100146 igt_assert((delta) >= 0); \
Eric Anholt8c641832009-03-26 17:15:11 -0700147 intel_batchbuffer_emit_reloc(batch, buf, delta, \
Daniel Vetter8ab88c92011-03-27 16:17:54 +0200148 read_domains, write_domain, 0); \
Eric Anholt8c641832009-03-26 17:15:11 -0700149} while (0)
150
Daniel Vetterec5f9e82014-03-13 01:13:28 +0100151/**
152 * ADVANCE_BATCH:
153 *
154 * Completes the batch command emission sequence started with #BEGIN_BATCH.
155 *
156 * This macro needs a pointer to an #intel_batchbuffer structure called batch in
157 * scope.
158 */
Eric Anholt8c641832009-03-26 17:15:11 -0700159#define ADVANCE_BATCH() do { \
Chris Wilson982f7eb2014-08-29 15:19:57 +0100160 igt_assert(batch->ptr == batch->end); \
161 batch->end = NULL; \
Eric Anholt8c641832009-03-26 17:15:11 -0700162} while(0)
163
Chris Wilson10552b52014-08-30 11:44:51 +0100164#define BLIT_COPY_BATCH_START(flags) do { \
165 BEGIN_BATCH(8, 2); \
166 OUT_BATCH(XY_SRC_COPY_BLT_CMD | \
167 XY_SRC_COPY_BLT_WRITE_ALPHA | \
168 XY_SRC_COPY_BLT_WRITE_RGB | \
169 (flags) | \
Chris Wilsond6af0042014-08-30 14:48:36 +0100170 (6 + 2*(batch->gen >= 8))); \
Ben Widawskyf4dfa372013-10-08 15:02:07 -0700171} while(0)
172
Chris Wilson10552b52014-08-30 11:44:51 +0100173#define COLOR_BLIT_COPY_BATCH_START(flags) do { \
174 BEGIN_BATCH(6, 1); \
175 OUT_BATCH(XY_COLOR_BLT_CMD_NOLEN | \
176 COLOR_BLT_WRITE_ALPHA | \
177 XY_COLOR_BLT_WRITE_RGB | \
Daniel Vetter9bb2ca32015-03-25 21:15:34 +0100178 (flags) | \
Chris Wilson10552b52014-08-30 11:44:51 +0100179 (4 + (batch->gen >= 8))); \
Ben Widawsky672911d2013-12-05 14:14:35 -0800180} while(0)
181
Imre Deakc1ee0bb2013-07-29 16:43:31 +0300182void
183intel_blt_copy(struct intel_batchbuffer *batch,
184 drm_intel_bo *src_bo, int src_x1, int src_y1, int src_pitch,
185 drm_intel_bo *dst_bo, int dst_x1, int dst_y1, int dst_pitch,
186 int width, int height, int bpp);
Chris Wilson95374222010-04-08 11:56:57 +0100187void intel_copy_bo(struct intel_batchbuffer *batch,
188 drm_intel_bo *dst_bo, drm_intel_bo *src_bo,
Daniel Vettereaccd442014-03-13 03:35:02 +0100189 long int size);
Chris Wilson95374222010-04-08 11:56:57 +0100190
Thomas Wood3b8e1212015-03-12 17:01:57 +0000191/*
Damien Lespiaucbd927c2015-03-03 14:10:57 +0000192 * Yf/Ys tiling
193 *
194 * Tiling mode in the I915_TILING_... namespace for new tiling modes which are
195 * defined in the kernel. (They are not fenceable so the kernel does not need
196 * to know about them.)
197 *
198 * They are to be used the the blitting routines below.
199 */
200#define I915_TILING_Yf 3
201#define I915_TILING_Ys 4
202
203/**
Daniel Vetter7754c4d2014-03-22 18:16:30 +0100204 * igt_buf:
205 * @bo: underlying libdrm buffer object
206 * @stride: stride of the buffer
207 * @tiling: tiling mode bits
208 * @data: pointer to the memory mapping of the buffer
209 * @size: size of the buffer object
Daniel Vetter7754c4d2014-03-22 18:16:30 +0100210 *
211 * This is a i-g-t buffer object wrapper structure which augments the baseline
212 * libdrm buffer object with suitable data needed by the render copy and the
Zhenyu Wang106f0bf2014-12-03 18:56:39 +0800213 * fill functions.
Daniel Vetter7754c4d2014-03-22 18:16:30 +0100214 */
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100215struct igt_buf {
Daniel Vetter7dc00012014-03-22 15:31:15 +0100216 drm_intel_bo *bo;
217 uint32_t stride;
218 uint32_t tiling;
219 uint32_t *data;
Daniel Vetter7dc00012014-03-22 15:31:15 +0100220 uint32_t size;
Thomas Wood52a3a2e2014-06-09 17:23:21 +0100221 /*< private >*/
Daniel Vetter7dc00012014-03-22 15:31:15 +0100222 unsigned num_tiles;
223};
224
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100225unsigned igt_buf_width(struct igt_buf *buf);
226unsigned igt_buf_height(struct igt_buf *buf);
Daniel Vetter7dc00012014-03-22 15:31:15 +0100227
Damien Lespiaucbd927c2015-03-03 14:10:57 +0000228void igt_blitter_fast_copy(struct intel_batchbuffer *batch,
229 struct igt_buf *src, unsigned src_x, unsigned src_y,
230 unsigned width, unsigned height,
231 struct igt_buf *dst, unsigned dst_x, unsigned dst_y);
232
Damien Lespiau672e88a2015-03-03 14:11:00 +0000233void igt_blitter_fast_copy__raw(int fd,
234 /* src */
235 uint32_t src_handle,
236 unsigned int src_stride,
237 unsigned int src_tiling,
238 unsigned int src_x, unsigned src_y,
239
240 /* size */
241 unsigned int width, unsigned int height,
242
243 /* dst */
244 uint32_t dst_handle,
245 unsigned int dst_stride,
246 unsigned int dst_tiling,
247 unsigned int dst_x, unsigned dst_y);
248
Daniel Vetter7754c4d2014-03-22 18:16:30 +0100249/**
250 * igt_render_copyfunc_t:
251 * @batch: batchbuffer object
252 * @context: libdrm hardware context to use
253 * @src: source i-g-t buffer object
254 * @src_x: source pixel x-coordination
255 * @src_y: source pixel y-coordination
256 * @width: width of the copied rectangle
257 * @height: height of the copied rectangle
258 * @dst: destination i-g-t buffer object
259 * @dst_x: destination pixel x-coordination
260 * @dst_y: destination pixel y-coordination
261 *
262 * This is the type of the per-platform render copy functions. The
263 * platform-specific implementation can be obtained by calling
264 * igt_get_render_copyfunc().
265 *
266 * A render copy function will emit a batchbuffer to the kernel which executes
267 * the specified blit copy operation using the render engine. @context is
268 * optional and can be NULL.
269 */
Daniel Vetter53a4d9e2014-03-22 15:49:02 +0100270typedef void (*igt_render_copyfunc_t)(struct intel_batchbuffer *batch,
271 drm_intel_context *context,
272 struct igt_buf *src, unsigned src_x, unsigned src_y,
273 unsigned width, unsigned height,
274 struct igt_buf *dst, unsigned dst_x, unsigned dst_y);
Daniel Vetter7dc00012014-03-22 15:31:15 +0100275
Daniel Vetter53a4d9e2014-03-22 15:49:02 +0100276igt_render_copyfunc_t igt_get_render_copyfunc(int devid);
Daniel Vetter7dc00012014-03-22 15:31:15 +0100277
Daniel Vetter7754c4d2014-03-22 18:16:30 +0100278/**
Zhenyu Wang106f0bf2014-12-03 18:56:39 +0800279 * igt_fillfunc_t:
Daniel Vetter7754c4d2014-03-22 18:16:30 +0100280 * @batch: batchbuffer object
281 * @dst: destination i-g-t buffer object
282 * @x: destination pixel x-coordination
283 * @y: destination pixel y-coordination
284 * @width: width of the filled rectangle
285 * @height: height of the filled rectangle
286 * @color: fill color to use
287 *
Zhenyu Wang106f0bf2014-12-03 18:56:39 +0800288 * This is the type of the per-platform fill functions using media
Zhenyu Wang10c6ad32014-12-03 19:05:09 +0800289 * or gpgpu pipeline. The platform-specific implementation can be obtained
290 * by calling igt_get_media_fillfunc() or igt_get_gpgpu_fillfunc().
Daniel Vetter7754c4d2014-03-22 18:16:30 +0100291 *
Zhenyu Wang106f0bf2014-12-03 18:56:39 +0800292 * A fill function will emit a batchbuffer to the kernel which executes
Zhenyu Wang10c6ad32014-12-03 19:05:09 +0800293 * the specified blit fill operation using the media/gpgpu engine.
Daniel Vetter7754c4d2014-03-22 18:16:30 +0100294 */
Zhenyu Wang106f0bf2014-12-03 18:56:39 +0800295typedef void (*igt_fillfunc_t)(struct intel_batchbuffer *batch,
296 struct igt_buf *dst,
297 unsigned x, unsigned y,
298 unsigned width, unsigned height,
299 uint8_t color);
Daniel Vetteraaebbc52014-03-22 15:35:16 +0100300
Zhenyu Wang106f0bf2014-12-03 18:56:39 +0800301igt_fillfunc_t igt_get_media_fillfunc(int devid);
Zhenyu Wang10c6ad32014-12-03 19:05:09 +0800302igt_fillfunc_t igt_get_gpgpu_fillfunc(int devid);
Daniel Vetteraaebbc52014-03-22 15:35:16 +0100303
Jeff McGeeaef46052015-03-12 10:52:08 -0700304/**
305 * igt_media_spinfunc_t:
306 * @batch: batchbuffer object
307 * @dst: destination i-g-t buffer object
308 * @spins: number of loops to execute
309 *
310 * This is the type of the per-platform media spin functions. The
311 * platform-specific implementation can be obtained by calling
312 * igt_get_media_spinfunc().
313 *
314 * The media spin function emits a batchbuffer for the render engine with
315 * the media pipeline selected. The workload consists of a single thread
316 * which spins in a tight loop the requested number of times. Each spin
317 * increments a counter whose final 32-bit value is written to the
318 * destination buffer on completion. This utility provides a simple way
319 * to keep the render engine busy for a set time for various tests.
320 */
321typedef void (*igt_media_spinfunc_t)(struct intel_batchbuffer *batch,
322 struct igt_buf *dst, uint32_t spins);
323
324igt_media_spinfunc_t igt_get_media_spinfunc(int devid);
325
Eric Anholt8c641832009-03-26 17:15:11 -0700326#endif