5db70fb6a261117841406e0001f455c50e1a05a0
[platform/upstream/intel-gpu-tools.git] / lib / intel_batchbuffer.h
1 #ifndef INTEL_BATCHBUFFER_H
2 #define INTEL_BATCHBUFFER_H
3
4 #include <stdint.h>
5 #include <intel_bufmgr.h>
6 #include "igt_core.h"
7 #include "intel_reg.h"
8
9 #define BATCH_SZ 4096
10 #define BATCH_RESERVED 16
11
12 struct intel_batchbuffer {
13         drm_intel_bufmgr *bufmgr;
14         uint32_t devid;
15         int gen;
16
17         drm_intel_bo *bo;
18
19         uint8_t buffer[BATCH_SZ];
20         uint8_t *ptr;
21         uint8_t *state;
22 };
23
24 struct intel_batchbuffer *intel_batchbuffer_alloc(drm_intel_bufmgr *bufmgr,
25                                                   uint32_t devid);
26
27 void intel_batchbuffer_free(struct intel_batchbuffer *batch);
28
29
30 void intel_batchbuffer_flush(struct intel_batchbuffer *batch);
31 void intel_batchbuffer_flush_on_ring(struct intel_batchbuffer *batch, int ring);
32 void intel_batchbuffer_flush_with_context(struct intel_batchbuffer *batch,
33                                           drm_intel_context *context);
34
35 void intel_batchbuffer_reset(struct intel_batchbuffer *batch);
36
37 void intel_batchbuffer_data(struct intel_batchbuffer *batch,
38                             const void *data, unsigned int bytes);
39
40 void intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
41                                   drm_intel_bo *buffer,
42                                   uint32_t delta,
43                                   uint32_t read_domains,
44                                   uint32_t write_domain,
45                                   int fenced);
46
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  */
52 #pragma GCC diagnostic ignored "-Winline"
53 static inline unsigned int
54 intel_batchbuffer_space(struct intel_batchbuffer *batch)
55 {
56         return (BATCH_SZ - BATCH_RESERVED) - (batch->ptr - batch->buffer);
57 }
58
59
60 static inline void
61 intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, uint32_t dword)
62 {
63         igt_assert(intel_batchbuffer_space(batch) >= 4);
64         *(uint32_t *) (batch->ptr) = dword;
65         batch->ptr += 4;
66 }
67
68 static inline void
69 intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
70                                 unsigned int sz)
71 {
72         igt_assert(sz < BATCH_SZ - BATCH_RESERVED);
73         if (intel_batchbuffer_space(batch) < sz)
74                 intel_batchbuffer_flush(batch);
75 }
76
77 /**
78  * BEGIN_BATCH:
79  * @n: number of DWORDS to emit
80  *
81  * Prepares a batch to emit @n DWORDS, flushing it if there's not enough space
82  * available.
83  *
84  * This macro needs a pointer to an #intel_batchbuffer structure called batch in
85  * scope.
86  */
87 #define BEGIN_BATCH(n) do {                                             \
88         intel_batchbuffer_require_space(batch, (n)*4);                  \
89 } while (0)
90
91 /**
92  * OUT_BATCH:
93  * @d: DWORD to emit
94  *
95  * Emits @d into a batch.
96  *
97  * This macro needs a pointer to an #intel_batchbuffer structure called batch in
98  * scope.
99  */
100 #define OUT_BATCH(d) intel_batchbuffer_emit_dword(batch, d)
101
102 /**
103  * OUT_RELOC_FENCED:
104  * @buf: relocation target libdrm buffer object
105  * @read_domains: gem domain bits for the relocation
106  * @write_domain: gem domain bit for the relocation
107  * @delta: delta value to add to @buffer's gpu address
108  *
109  * Emits a fenced relocation into a batch.
110  *
111  * This macro needs a pointer to an #intel_batchbuffer structure called batch in
112  * scope.
113  */
114 #define OUT_RELOC_FENCED(buf, read_domains, write_domain, delta) do {           \
115         igt_assert((delta) >= 0);                                               \
116         intel_batchbuffer_emit_reloc(batch, buf, delta,                 \
117                                      read_domains, write_domain, 1);    \
118 } while (0)
119
120 /**
121  * OUT_RELOC:
122  * @buf: relocation target libdrm buffer object
123  * @read_domains: gem domain bits for the relocation
124  * @write_domain: gem domain bit for the relocation
125  * @delta: delta value to add to @buffer's gpu address
126  *
127  * Emits a normal, unfenced relocation into a batch.
128  *
129  * This macro needs a pointer to an #intel_batchbuffer structure called batch in
130  * scope.
131  */
132 #define OUT_RELOC(buf, read_domains, write_domain, delta) do {          \
133         igt_assert((delta) >= 0);                                               \
134         intel_batchbuffer_emit_reloc(batch, buf, delta,                 \
135                                      read_domains, write_domain, 0);    \
136 } while (0)
137
138 /**
139  * ADVANCE_BATCH:
140  *
141  * Completes the batch command emission sequence started with #BEGIN_BATCH.
142  *
143  * This macro needs a pointer to an #intel_batchbuffer structure called batch in
144  * scope.
145  */
146 #define ADVANCE_BATCH() do {                                            \
147 } while(0)
148
149 #define BLIT_COPY_BATCH_START(devid, flags) do { \
150         if (intel_gen(devid) >= 8) { \
151                 BEGIN_BATCH(10); \
152                 OUT_BATCH(XY_SRC_COPY_BLT_CMD | \
153                                 XY_SRC_COPY_BLT_WRITE_ALPHA | \
154                                 XY_SRC_COPY_BLT_WRITE_RGB | \
155                                 (flags) | 8); \
156         } else { \
157                 BEGIN_BATCH(8); \
158                 OUT_BATCH(XY_SRC_COPY_BLT_CMD | \
159                                 XY_SRC_COPY_BLT_WRITE_ALPHA | \
160                                 XY_SRC_COPY_BLT_WRITE_RGB | \
161                                 (flags) | 6); \
162         } \
163 } while(0)
164
165 #define COLOR_BLIT_COPY_BATCH_START(devid, flags) do { \
166         if (intel_gen(devid) >= 8) { \
167                 BEGIN_BATCH(8); \
168                 OUT_BATCH(MI_NOOP); \
169                 OUT_BATCH(XY_COLOR_BLT_CMD_NOLEN | 0x5 | \
170                                 COLOR_BLT_WRITE_ALPHA | \
171                                 XY_COLOR_BLT_WRITE_RGB); \
172         } else { \
173                 BEGIN_BATCH(6); \
174                 OUT_BATCH(XY_COLOR_BLT_CMD_NOLEN | 0x4 | \
175                                 COLOR_BLT_WRITE_ALPHA | \
176                                 XY_COLOR_BLT_WRITE_RGB); \
177         } \
178 } while(0)
179
180 /**
181  * BLIT_RELOC_UDW:
182  * @devid: pci device id of the drm device
183  *
184  * Emits the upper relocation DWORD on gen8+ and nothing on earlier generations.
185  */
186 #define BLIT_RELOC_UDW(devid) do { \
187         if (intel_gen(devid) >= 8) { \
188                 OUT_BATCH(0); \
189         } \
190 } while(0)
191
192 void
193 intel_blt_copy(struct intel_batchbuffer *batch,
194               drm_intel_bo *src_bo, int src_x1, int src_y1, int src_pitch,
195               drm_intel_bo *dst_bo, int dst_x1, int dst_y1, int dst_pitch,
196               int width, int height, int bpp);
197 void intel_copy_bo(struct intel_batchbuffer *batch,
198                    drm_intel_bo *dst_bo, drm_intel_bo *src_bo,
199                    long int size);
200
201 /**
202  * igt_buf:
203  * @bo: underlying libdrm buffer object
204  * @stride: stride of the buffer
205  * @tiling: tiling mode bits
206  * @data: pointer to the memory mapping of the buffer
207  * @size: size of the buffer object
208  *
209  * This is a i-g-t buffer object wrapper structure which augments the baseline
210  * libdrm buffer object with suitable data needed by the render copy and the
211  * media fill functions.
212  */
213 struct igt_buf {
214     drm_intel_bo *bo;
215     uint32_t stride;
216     uint32_t tiling;
217     uint32_t *data;
218     uint32_t size;
219     /*< private >*/
220     unsigned num_tiles;
221 };
222
223 unsigned igt_buf_width(struct igt_buf *buf);
224 unsigned igt_buf_height(struct igt_buf *buf);
225
226 /**
227  * igt_render_copyfunc_t:
228  * @batch: batchbuffer object
229  * @context: libdrm hardware context to use
230  * @src: source i-g-t buffer object
231  * @src_x: source pixel x-coordination
232  * @src_y: source pixel y-coordination
233  * @width: width of the copied rectangle
234  * @height: height of the copied rectangle
235  * @dst: destination i-g-t buffer object
236  * @dst_x: destination pixel x-coordination
237  * @dst_y: destination pixel y-coordination
238  *
239  * This is the type of the per-platform render copy functions. The
240  * platform-specific implementation can be obtained by calling
241  * igt_get_render_copyfunc().
242  *
243  * A render copy function will emit a batchbuffer to the kernel which executes
244  * the specified blit copy operation using the render engine. @context is
245  * optional and can be NULL.
246  */
247 typedef void (*igt_render_copyfunc_t)(struct intel_batchbuffer *batch,
248                                       drm_intel_context *context,
249                                       struct igt_buf *src, unsigned src_x, unsigned src_y,
250                                       unsigned width, unsigned height,
251                                       struct igt_buf *dst, unsigned dst_x, unsigned dst_y);
252
253 igt_render_copyfunc_t igt_get_render_copyfunc(int devid);
254
255 /**
256  * igt_media_fillfunc_t:
257  * @batch: batchbuffer object
258  * @dst: destination i-g-t buffer object
259  * @x: destination pixel x-coordination
260  * @y: destination pixel y-coordination
261  * @width: width of the filled rectangle
262  * @height: height of the filled rectangle
263  * @color: fill color to use
264  *
265  * This is the type of the per-platform media fill functions. The
266  * platform-specific implementation can be obtained by calling
267  * igt_get_media_fillfunc().
268  *
269  * A media fill function will emit a batchbuffer to the kernel which executes
270  * the specified blit fill operation using the media engine.
271  */
272 typedef void (*igt_media_fillfunc_t)(struct intel_batchbuffer *batch,
273                                      struct igt_buf *dst,
274                                      unsigned x, unsigned y,
275                                      unsigned width, unsigned height,
276                                      uint8_t color);
277
278 igt_media_fillfunc_t igt_get_media_fillfunc(int devid);
279
280 #endif