blob: 77a63347f3b8804a44b48b21618aaea94fcdc89c [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>
Daniel Vetter0e22f142014-03-22 19:27:04 +01006#include "igt_core.h"
Daniel Vetter6cfcd712014-03-22 20:07:35 +01007#include "intel_reg.h"
Eric Anholt8c641832009-03-26 17:15:11 -07008
9#define BATCH_SZ 4096
10#define BATCH_RESERVED 16
11
Chris Wilson719ffef2011-05-22 10:34:12 +010012struct intel_batchbuffer {
Eric Anholt8c641832009-03-26 17:15:11 -070013 drm_intel_bufmgr *bufmgr;
Chris Wilsond4d769a2010-10-26 10:59:18 +010014 uint32_t devid;
Chris Wilson23d961e2014-08-29 14:49:59 +010015 int gen;
Eric Anholt8c641832009-03-26 17:15:11 -070016
17 drm_intel_bo *bo;
18
Chris Wilson371f87f2011-02-01 10:53:57 +000019 uint8_t buffer[BATCH_SZ];
Chris Wilson982f7eb2014-08-29 15:19:57 +010020 uint8_t *ptr, *end;
Chris Wilson1945e2a2012-12-06 17:18:52 +000021 uint8_t *state;
Eric Anholt8c641832009-03-26 17:15:11 -070022};
23
Chris Wilsond4d769a2010-10-26 10:59:18 +010024struct intel_batchbuffer *intel_batchbuffer_alloc(drm_intel_bufmgr *bufmgr,
25 uint32_t devid);
Eric Anholt8c641832009-03-26 17:15:11 -070026
27void intel_batchbuffer_free(struct intel_batchbuffer *batch);
28
29
30void intel_batchbuffer_flush(struct intel_batchbuffer *batch);
Daniel Vetterd42b7f92011-09-07 09:20:36 +020031void intel_batchbuffer_flush_on_ring(struct intel_batchbuffer *batch, int ring);
Ben Widawskya635a5a2012-01-15 14:52:33 -080032void intel_batchbuffer_flush_with_context(struct intel_batchbuffer *batch,
33 drm_intel_context *context);
Eric Anholt8c641832009-03-26 17:15:11 -070034
35void intel_batchbuffer_reset(struct intel_batchbuffer *batch);
36
37void intel_batchbuffer_data(struct intel_batchbuffer *batch,
38 const void *data, unsigned int bytes);
39
40void intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
41 drm_intel_bo *buffer,
Chris Wilson982f7eb2014-08-29 15:19:57 +010042 uint64_t delta,
Eric Anholt8c641832009-03-26 17:15:11 -070043 uint32_t read_domains,
Daniel Vetter8ab88c92011-03-27 16:17:54 +020044 uint32_t write_domain,
45 int fenced);
Eric Anholt8c641832009-03-26 17:15:11 -070046
47/* Inline functions - might actually be better off with these
48 * non-inlined. Certainly better off switching all command packets to
49 * be passed as structs rather than dwords, but that's a little bit of
50 * work...
51 */
Ben Widawsky802bd742012-01-15 13:41:42 -080052#pragma GCC diagnostic ignored "-Winline"
Oscar Mateo5032e7b2013-11-12 11:50:42 +000053static inline unsigned int
Eric Anholt8c641832009-03-26 17:15:11 -070054intel_batchbuffer_space(struct intel_batchbuffer *batch)
55{
Chris Wilson371f87f2011-02-01 10:53:57 +000056 return (BATCH_SZ - BATCH_RESERVED) - (batch->ptr - batch->buffer);
Eric Anholt8c641832009-03-26 17:15:11 -070057}
58
59
60static inline void
61intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, uint32_t dword)
62{
Daniel Vetter0e22f142014-03-22 19:27:04 +010063 igt_assert(intel_batchbuffer_space(batch) >= 4);
Eric Anholt8c641832009-03-26 17:15:11 -070064 *(uint32_t *) (batch->ptr) = dword;
65 batch->ptr += 4;
66}
67
68static inline void
69intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
70 unsigned int sz)
71{
Daniel Vetter0e22f142014-03-22 19:27:04 +010072 igt_assert(sz < BATCH_SZ - BATCH_RESERVED);
Eric Anholt8c641832009-03-26 17:15:11 -070073 if (intel_batchbuffer_space(batch) < sz)
74 intel_batchbuffer_flush(batch);
75}
76
Daniel Vetterec5f9e82014-03-13 01:13:28 +010077/**
78 * BEGIN_BATCH:
79 * @n: number of DWORDS to emit
Chris Wilson10552b52014-08-30 11:44:51 +010080 * @r: number of RELOCS to emit
Daniel Vetterec5f9e82014-03-13 01:13:28 +010081 *
82 * Prepares a batch to emit @n DWORDS, flushing it if there's not enough space
83 * available.
84 *
85 * This macro needs a pointer to an #intel_batchbuffer structure called batch in
86 * scope.
87 */
Chris Wilson10552b52014-08-30 11:44:51 +010088#define BEGIN_BATCH(n, r) do { \
89 int __n = (n); \
Chris Wilson982f7eb2014-08-29 15:19:57 +010090 igt_assert(batch->end == NULL); \
Chris Wilson10552b52014-08-30 11:44:51 +010091 if (batch->gen >= 8) __n += r; \
92 __n *= 4; \
93 intel_batchbuffer_require_space(batch, __n); \
94 batch->end = batch->ptr + __n; \
Eric Anholt8c641832009-03-26 17:15:11 -070095} while (0)
96
Daniel Vetterec5f9e82014-03-13 01:13:28 +010097/**
98 * OUT_BATCH:
99 * @d: DWORD to emit
100 *
101 * Emits @d into a batch.
102 *
103 * This macro needs a pointer to an #intel_batchbuffer structure called batch in
104 * scope.
105 */
Eric Anholt8c641832009-03-26 17:15:11 -0700106#define OUT_BATCH(d) intel_batchbuffer_emit_dword(batch, d)
107
Daniel Vetterec5f9e82014-03-13 01:13:28 +0100108/**
109 * OUT_RELOC_FENCED:
110 * @buf: relocation target libdrm buffer object
111 * @read_domains: gem domain bits for the relocation
112 * @write_domain: gem domain bit for the relocation
113 * @delta: delta value to add to @buffer's gpu address
114 *
115 * Emits a fenced relocation into a batch.
116 *
117 * This macro needs a pointer to an #intel_batchbuffer structure called batch in
118 * scope.
119 */
Daniel Vetter8ab88c92011-03-27 16:17:54 +0200120#define OUT_RELOC_FENCED(buf, read_domains, write_domain, delta) do { \
Daniel Vetter0e22f142014-03-22 19:27:04 +0100121 igt_assert((delta) >= 0); \
Daniel Vetter8ab88c92011-03-27 16:17:54 +0200122 intel_batchbuffer_emit_reloc(batch, buf, delta, \
123 read_domains, write_domain, 1); \
124} while (0)
125
Daniel Vetterec5f9e82014-03-13 01:13:28 +0100126/**
Mika Kuoppaladb259732014-03-26 17:24:43 +0200127 * OUT_RELOC:
Daniel Vetterec5f9e82014-03-13 01:13:28 +0100128 * @buf: relocation target libdrm buffer object
129 * @read_domains: gem domain bits for the relocation
130 * @write_domain: gem domain bit for the relocation
131 * @delta: delta value to add to @buffer's gpu address
132 *
133 * Emits a normal, unfenced relocation into a batch.
134 *
135 * This macro needs a pointer to an #intel_batchbuffer structure called batch in
136 * scope.
137 */
Eric Anholt8c641832009-03-26 17:15:11 -0700138#define OUT_RELOC(buf, read_domains, write_domain, delta) do { \
Daniel Vetter0e22f142014-03-22 19:27:04 +0100139 igt_assert((delta) >= 0); \
Eric Anholt8c641832009-03-26 17:15:11 -0700140 intel_batchbuffer_emit_reloc(batch, buf, delta, \
Daniel Vetter8ab88c92011-03-27 16:17:54 +0200141 read_domains, write_domain, 0); \
Eric Anholt8c641832009-03-26 17:15:11 -0700142} while (0)
143
Daniel Vetterec5f9e82014-03-13 01:13:28 +0100144/**
145 * ADVANCE_BATCH:
146 *
147 * Completes the batch command emission sequence started with #BEGIN_BATCH.
148 *
149 * This macro needs a pointer to an #intel_batchbuffer structure called batch in
150 * scope.
151 */
Eric Anholt8c641832009-03-26 17:15:11 -0700152#define ADVANCE_BATCH() do { \
Chris Wilson982f7eb2014-08-29 15:19:57 +0100153 igt_assert(batch->ptr == batch->end); \
154 batch->end = NULL; \
Eric Anholt8c641832009-03-26 17:15:11 -0700155} while(0)
156
Chris Wilson10552b52014-08-30 11:44:51 +0100157#define BLIT_COPY_BATCH_START(flags) do { \
158 BEGIN_BATCH(8, 2); \
159 OUT_BATCH(XY_SRC_COPY_BLT_CMD | \
160 XY_SRC_COPY_BLT_WRITE_ALPHA | \
161 XY_SRC_COPY_BLT_WRITE_RGB | \
162 (flags) | \
Chris Wilsond6af0042014-08-30 14:48:36 +0100163 (6 + 2*(batch->gen >= 8))); \
Ben Widawskyf4dfa372013-10-08 15:02:07 -0700164} while(0)
165
Chris Wilson10552b52014-08-30 11:44:51 +0100166#define COLOR_BLIT_COPY_BATCH_START(flags) do { \
167 BEGIN_BATCH(6, 1); \
168 OUT_BATCH(XY_COLOR_BLT_CMD_NOLEN | \
169 COLOR_BLT_WRITE_ALPHA | \
170 XY_COLOR_BLT_WRITE_RGB | \
171 (4 + (batch->gen >= 8))); \
Ben Widawsky672911d2013-12-05 14:14:35 -0800172} while(0)
173
Imre Deakc1ee0bb2013-07-29 16:43:31 +0300174void
175intel_blt_copy(struct intel_batchbuffer *batch,
176 drm_intel_bo *src_bo, int src_x1, int src_y1, int src_pitch,
177 drm_intel_bo *dst_bo, int dst_x1, int dst_y1, int dst_pitch,
178 int width, int height, int bpp);
Chris Wilson95374222010-04-08 11:56:57 +0100179void intel_copy_bo(struct intel_batchbuffer *batch,
180 drm_intel_bo *dst_bo, drm_intel_bo *src_bo,
Daniel Vettereaccd442014-03-13 03:35:02 +0100181 long int size);
Chris Wilson95374222010-04-08 11:56:57 +0100182
Daniel Vetter7754c4d2014-03-22 18:16:30 +0100183/**
184 * igt_buf:
185 * @bo: underlying libdrm buffer object
186 * @stride: stride of the buffer
187 * @tiling: tiling mode bits
188 * @data: pointer to the memory mapping of the buffer
189 * @size: size of the buffer object
Daniel Vetter7754c4d2014-03-22 18:16:30 +0100190 *
191 * This is a i-g-t buffer object wrapper structure which augments the baseline
192 * libdrm buffer object with suitable data needed by the render copy and the
193 * media fill functions.
Daniel Vetter7754c4d2014-03-22 18:16:30 +0100194 */
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100195struct igt_buf {
Daniel Vetter7dc00012014-03-22 15:31:15 +0100196 drm_intel_bo *bo;
197 uint32_t stride;
198 uint32_t tiling;
199 uint32_t *data;
Daniel Vetter7dc00012014-03-22 15:31:15 +0100200 uint32_t size;
Thomas Wood52a3a2e2014-06-09 17:23:21 +0100201 /*< private >*/
Daniel Vetter7dc00012014-03-22 15:31:15 +0100202 unsigned num_tiles;
203};
204
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100205unsigned igt_buf_width(struct igt_buf *buf);
206unsigned igt_buf_height(struct igt_buf *buf);
Daniel Vetter7dc00012014-03-22 15:31:15 +0100207
Daniel Vetter7754c4d2014-03-22 18:16:30 +0100208/**
209 * igt_render_copyfunc_t:
210 * @batch: batchbuffer object
211 * @context: libdrm hardware context to use
212 * @src: source i-g-t buffer object
213 * @src_x: source pixel x-coordination
214 * @src_y: source pixel y-coordination
215 * @width: width of the copied rectangle
216 * @height: height of the copied rectangle
217 * @dst: destination i-g-t buffer object
218 * @dst_x: destination pixel x-coordination
219 * @dst_y: destination pixel y-coordination
220 *
221 * This is the type of the per-platform render copy functions. The
222 * platform-specific implementation can be obtained by calling
223 * igt_get_render_copyfunc().
224 *
225 * A render copy function will emit a batchbuffer to the kernel which executes
226 * the specified blit copy operation using the render engine. @context is
227 * optional and can be NULL.
228 */
Daniel Vetter53a4d9e2014-03-22 15:49:02 +0100229typedef void (*igt_render_copyfunc_t)(struct intel_batchbuffer *batch,
230 drm_intel_context *context,
231 struct igt_buf *src, unsigned src_x, unsigned src_y,
232 unsigned width, unsigned height,
233 struct igt_buf *dst, unsigned dst_x, unsigned dst_y);
Daniel Vetter7dc00012014-03-22 15:31:15 +0100234
Daniel Vetter53a4d9e2014-03-22 15:49:02 +0100235igt_render_copyfunc_t igt_get_render_copyfunc(int devid);
Daniel Vetter7dc00012014-03-22 15:31:15 +0100236
Daniel Vetter7754c4d2014-03-22 18:16:30 +0100237/**
238 * igt_media_fillfunc_t:
239 * @batch: batchbuffer object
240 * @dst: destination i-g-t buffer object
241 * @x: destination pixel x-coordination
242 * @y: destination pixel y-coordination
243 * @width: width of the filled rectangle
244 * @height: height of the filled rectangle
245 * @color: fill color to use
246 *
247 * This is the type of the per-platform media fill functions. The
248 * platform-specific implementation can be obtained by calling
249 * igt_get_media_fillfunc().
250 *
251 * A media fill function will emit a batchbuffer to the kernel which executes
252 * the specified blit fill operation using the media engine.
253 */
Daniel Vetter53a4d9e2014-03-22 15:49:02 +0100254typedef void (*igt_media_fillfunc_t)(struct intel_batchbuffer *batch,
255 struct igt_buf *dst,
256 unsigned x, unsigned y,
257 unsigned width, unsigned height,
258 uint8_t color);
Daniel Vetteraaebbc52014-03-22 15:35:16 +0100259
Daniel Vetter53a4d9e2014-03-22 15:49:02 +0100260igt_media_fillfunc_t igt_get_media_fillfunc(int devid);
Daniel Vetteraaebbc52014-03-22 15:35:16 +0100261
Eric Anholt8c641832009-03-26 17:15:11 -0700262#endif