1/* wld: intel/blt.h
2 *
3 * Copyright (c) 2013, 2014 Michael Forney
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24#ifndef WLD_INTEL_BLT_H
25#define WLD_INTEL_BLT_H
26
27#include <i915_drm.h>
28#include <intel_bufmgr.h>
29
30#define INTEL_CLIENT_BLT 0x2
31
32enum blt_op {
33 BLT_OP_XY_SETUP_BLT = 0x01,
34 BLT_OP_XY_TEXT_BLT = 0x26,
35 BLT_OP_XY_TEXT_IMMEDIATE_BLT = 0x31,
36 BLT_OP_XY_COLOR_BLT = 0x50,
37 BLT_OP_XY_SRC_COPY_BLT = 0x53
38};
39
40enum blt_32bpp_mask {
41 BLT_32BPP_MASK_ALPHA = (1 << 0),
42 BLT_32BPP_MASK_RGB = (1 << 1)
43};
44
45enum blt_packing {
46 BLT_PACKING_BIT = 0,
47 BLT_PACKING_BYTE = 1
48};
49
50enum blt_color_depth {
51 BLT_COLOR_DEPTH_8BIT = 0x0,
52 BLT_COLOR_DEPTH_16BIT_565 = 0x1,
53 BLT_COLOR_DEPTH_16BIT_1555 = 0x2,
54 BLT_COLOR_DEPTH_32BIT = 0x3
55};
56
57enum blt_raster_operation {
58 BLT_RASTER_OPERATION_SRC = 0xcc,
59 BLT_RASTER_OPERATION_PAT = 0xf0
60};
61
62/* BR00 : BLT Opcode & Control */
63#define BLT_BR00_CLIENT(x) ((x) << 29) /* 31:29 */
64#define BLT_BR00_OP(x) ((x) << 22) /* 28:22 */
65#define BLT_BR00_32BPP_MASK(x) ((x) << 20) /* 21:20 */
66 /* 19:17 */
67#define BLT_BR00_PACKING(x) ((x) << 16) /* 16 */
68#define BLT_BR00_SRC_TILING_ENABLE(x) ((x) << 15) /* 15 */
69 /* 14:12 */
70#define BLT_BR00_DST_TILING_ENABLE(x) ((x) << 11) /* 11 */
71#define BLT_BR00_DWORD_LENGTH(x) ((x) << 0) /* 7:0 */
72
73/* BR01 : Setup BLT Raster OP, Control, and Destination Offset */
74#define BLT_BR01_SOLID_PATTERN(x) ((x) << 31) /* 31 */
75#define BLT_BR01_CLIPPING_ENABLE(x) ((x) << 30) /* 30 */
76#define BLT_BR01_MONO_SRC_TRANSPARENCY(x) ((x) << 29) /* 29 */
77#define BLT_BR01_MONO_PAT_TRANSPARENCY(x) ((x) << 28) /* 28 */
78#define BLT_BR01_COLOR_DEPTH(x) ((x) << 24) /* 25:24 */
79#define BLT_BR01_RASTER_OPERATION(x) ((x) << 16) /* 23:16 */
80#define BLT_BR01_DST_PITCH(x) ((x) << 0) /* 15:0 */
81
82/* BR05 : Setup Expansion Background Color */
83#define BLT_BR05_BACKGROUND_COLOR(x) ((x) << 0) /* 31:0 */
84
85/* BR06 : Setup Expansion Foreground Color */
86#define BLT_BR06_FOREGROUND_COLOR(x) ((x) << 0) /* 31:0 */
87
88/* BR07 : Setup Blit Color Pattern Address Low Bits */
89/* 31:29 */
90#define BLT_BR07_PAT_ADDRESS(x) ((x) << 6) /* 28:6 */
91 /* 5:0 */
92
93/* BR09 : Destination Address Low Bits */
94/* 31:29 */
95#define BLT_BR09_DST_ADDRESS(x) ((x) << 0) /* 28:0 */
96
97/* BR11 : Source Pitch */
98/* 31:16 */
99#define BLT_BR11_SRC_PITCH(x) ((x) << 0) /* 15:0 */
100
101/* BR12 : Source Address Low Bits */
102/* 31:29 */
103#define BLT_BR12_SRC_ADDRESS(x) ((x) << 0) /* 28:0 */
104
105/* BR13 : BLT Raster OP, Control, and Destination Pitch */
106#define BLT_BR13_SOLID_PATTERN(x) ((x) << 31) /* 31 */
107#define BLT_BR13_CLIPPING_ENABLE(x) ((x) << 30) /* 30 */
108#define BLT_BR13_MONO_SRC_TRANSPARENT(x) ((x) << 29) /* 29 */
109#define BLT_BR13_MONO_PAT_TRANSPARENT(x) ((x) << 28) /* 28 */
110#define BLT_BR13_COLOR_DEPTH(x) ((x) << 24) /* 25:24 */
111#define BLT_BR13_RASTER_OPERATION(x) ((x) << 16) /* 23:16 */
112#define BLT_BR13_DST_PITCH(x) ((x) << 0) /* 15:0 */
113
114/* BR16 : Pattern Expansion Background & Solid Pattern Color */
115#define BLT_BR16_COLOR(x) ((x) << 0) /* 31 : 0 */
116
117/* BR22 : Destination Top Left */
118#define BLT_BR22_DST_Y1(x) ((x) << 16) /* 31:16 */
119#define BLT_BR22_DST_X1(x) ((x) << 0) /* 16:0 */
120
121/* BR23 : Destination Bottom Right */
122#define BLT_BR23_DST_Y2(x) ((x) << 16) /* 31:16 */
123#define BLT_BR23_DST_X2(x) ((x) << 0) /* 16:0 */
124
125/* BR24 : Clip Rectangle Top Left */
126/* 31 */
127#define BLT_BR24_CLP_Y1(x) ((x) << 16) /* 30:16 */
128 /* 15 */
129#define BLT_BR24_CLP_X1(x) ((x) << 0) /* 14:0 */
130
131/* BR25 : Clip Rectangle Bottom Right */
132/* 31 */
133#define BLT_BR25_CLP_Y2(x) ((x) << 16) /* 30:16 */
134 /* 15 */
135#define BLT_BR25_CLP_X2(x) ((x) << 0) /* 14:0 */
136
137/* BR26 : Source Top Left */
138#define BLT_BR26_SRC_Y1(x) ((x) << 16) /* 31:16 */
139#define BLT_BR26_SRC_X1(x) ((x) << 0) /* 15:0 */
140
141/* BR27 : Destination Address High Bits */
142/* 31:16 */
143#define BLT_BR27_DST_ADDRESS_HI(x) ((x) << 0) /* 15:0 */
144
145/* BR28 : Source Address High Bits */
146/* 31:16 */
147#define BLT_BR28_SRC_ADDRESS_HI(x) ((x) << 0) /* 15:0 */
148
149/* BR30 : Setup Blit Color Pattern Address High Bits */
150/* 31:16 */
151#define BLT_BR30_PAT_ADDRESS_HI(x) ((x) << 0) /* 15:0 */
152
153static inline void
154xy_setup_blt(struct intel_batch *batch,
155 bool monochrome_source_transparency,
156 uint8_t raster_operation,
157 uint32_t background_color,
158 uint32_t foreground_color,
159 drm_intel_bo *dst, uint16_t dst_pitch)
160{
161 uint32_t tiling_mode, swizzle_mode;
162
163 intel_batch_ensure_space(batch, GEN(batch, 8) ? 10 : 8);
164
165 drm_intel_bo_get_tiling(dst, &tiling_mode, &swizzle_mode);
166 drm_intel_bo_emit_reloc_fence(batch->bo, intel_batch_offset(batch, 4), dst, 0,
167 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER);
168
169 intel_batch_add_dwords(batch, 4,
170 BLT_BR00_CLIENT(INTEL_CLIENT_BLT)
171 | BLT_BR00_OP(BLT_OP_XY_SETUP_BLT)
172 | BLT_BR00_32BPP_MASK(BLT_32BPP_MASK_ALPHA | BLT_32BPP_MASK_RGB)
173 | BLT_BR00_DST_TILING_ENABLE(tiling_mode != I915_TILING_NONE)
174 | BLT_BR00_DWORD_LENGTH(GEN(batch, 8) ? 8 : 6),
175
176 BLT_BR01_CLIPPING_ENABLE(false)
177 | BLT_BR01_MONO_SRC_TRANSPARENCY(monochrome_source_transparency)
178 | BLT_BR01_COLOR_DEPTH(BLT_COLOR_DEPTH_32BIT)
179 | BLT_BR01_RASTER_OPERATION(raster_operation)
180 | BLT_BR01_DST_PITCH(tiling_mode == I915_TILING_NONE
181 ? dst_pitch
182 : dst_pitch >> 2),
183
184 /* XXX: No clipping yet */
185 BLT_BR24_CLP_Y1(0)
186 | BLT_BR24_CLP_X1(0),
187
188 BLT_BR25_CLP_Y2(0)
189 | BLT_BR25_CLP_X2(0));
190
191 intel_batch_add_dwords(batch, GEN(batch, 8) ? 2 : 1,
192 BLT_BR09_DST_ADDRESS(dst->offset64),
193 /* if gen8 */
194 BLT_BR27_DST_ADDRESS_HI(dst->offset64 >> 32));
195
196 intel_batch_add_dwords(batch, 2,
197 BLT_BR05_BACKGROUND_COLOR(background_color),
198 BLT_BR06_FOREGROUND_COLOR(foreground_color));
199
200 intel_batch_add_dwords(batch, GEN(batch, 8) ? 2 : 1,
201 BLT_BR07_PAT_ADDRESS(0),
202 /* if gen8 */
203 BLT_BR30_PAT_ADDRESS_HI(0));
204}
205
206static inline int
207xy_text_blt(struct intel_batch *batch,
208 drm_intel_bo *src, uint32_t src_offset,
209 drm_intel_bo *dst,
210 int16_t dst_x1, int16_t dst_y1,
211 int16_t dst_x2, int16_t dst_y2)
212{
213 uint32_t tiling_mode, swizzle_mode;
214
215 if (!intel_batch_check_space(batch, GEN(batch, 8) ? 5 : 4))
216 return INTEL_BATCH_NO_SPACE;
217
218 drm_intel_bo_get_tiling(dst, &tiling_mode, &swizzle_mode);
219
220 drm_intel_bo_emit_reloc_fence(batch->bo, intel_batch_offset(batch, 3), src, src_offset,
221 I915_GEM_DOMAIN_RENDER, 0);
222
223 intel_batch_add_dwords(batch, 3,
224 BLT_BR00_CLIENT(INTEL_CLIENT_BLT)
225 | BLT_BR00_OP(BLT_OP_XY_TEXT_BLT)
226 | BLT_BR00_PACKING(BLT_PACKING_BYTE)
227 | BLT_BR00_DST_TILING_ENABLE(tiling_mode != I915_TILING_NONE)
228 | BLT_BR00_DWORD_LENGTH(GEN(batch, 8) ? 3 : 2),
229
230 BLT_BR22_DST_Y1(dst_y1) | BLT_BR22_DST_X1(dst_x1),
231 BLT_BR23_DST_Y2(dst_y2) | BLT_BR23_DST_X2(dst_x2));
232
233 intel_batch_add_dwords(batch, GEN(batch, 8) ? 2 : 1,
234 BLT_BR12_SRC_ADDRESS(src->offset64 + src_offset),
235 /* if gen8 */
236 BLT_BR28_SRC_ADDRESS_HI((src->offset64 + src_offset) >> 32));
237
238 return INTEL_BATCH_SUCCESS;
239}
240
241static inline int
242xy_text_immediate_blt(struct intel_batch *batch,
243 drm_intel_bo *dst,
244 int16_t dst_x1, int16_t dst_y1,
245 int16_t dst_x2, int16_t dst_y2,
246 uint16_t count, uint32_t *immediates)
247{
248 /* Round up to the next even number. */
249 uint8_t dwords = (count + 1) & ~1;
250 uint32_t index;
251 uint32_t tiling_mode, swizzle_mode;
252
253 if (!intel_batch_check_space(batch, 3 + dwords))
254 return INTEL_BATCH_NO_SPACE;
255
256 drm_intel_bo_get_tiling(dst, &tiling_mode, &swizzle_mode);
257
258 intel_batch_add_dwords(batch, 3,
259 BLT_BR00_CLIENT(INTEL_CLIENT_BLT)
260 | BLT_BR00_OP(BLT_OP_XY_TEXT_IMMEDIATE_BLT)
261 | BLT_BR00_PACKING(BLT_PACKING_BYTE)
262 | BLT_BR00_DST_TILING_ENABLE(tiling_mode != I915_TILING_NONE)
263 | BLT_BR00_DWORD_LENGTH(1 + dwords),
264
265 BLT_BR22_DST_Y1(dst_y1) | BLT_BR22_DST_X1(dst_x1),
266 BLT_BR23_DST_Y2(dst_y2) | BLT_BR23_DST_X2(dst_x2));
267
268 for (index = 0; index < count; ++index)
269 intel_batch_add_dword(batch, *immediates++);
270
271 /* From BLT engine documentation:
272 *
273 * The IMMEDIATE_BLT data MUST transfer an even number of doublewords. The
274 * BLT engine will hang if it does not get an even number of doublewords. */
275 if (count & 1)
276 intel_batch_add_dword(batch, 0);
277
278 return INTEL_BATCH_SUCCESS;
279}
280
281static inline void
282xy_src_copy_blt(struct intel_batch *batch,
283 drm_intel_bo *src, uint16_t src_pitch,
284 uint16_t src_x, uint16_t src_y,
285 drm_intel_bo *dst, uint16_t dst_pitch,
286 uint16_t dst_x, uint16_t dst_y,
287 uint16_t width, uint16_t height)
288{
289 uint32_t src_tiling_mode, dst_tiling_mode, swizzle;
290
291 intel_batch_ensure_space(batch, GEN(batch, 8) ? 10 : 8);
292
293 drm_intel_bo_get_tiling(dst, &dst_tiling_mode, &swizzle);
294 drm_intel_bo_get_tiling(src, &src_tiling_mode, &swizzle);
295
296 drm_intel_bo_emit_reloc_fence(batch->bo, intel_batch_offset(batch, 4), dst, 0,
297 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER);
298 drm_intel_bo_emit_reloc_fence(batch->bo, intel_batch_offset(batch, GEN(batch, 8) ? 8 : 7), src, 0,
299 I915_GEM_DOMAIN_RENDER, 0);
300
301 intel_batch_add_dwords(batch, 4,
302 BLT_BR00_CLIENT(INTEL_CLIENT_BLT)
303 | BLT_BR00_OP(BLT_OP_XY_SRC_COPY_BLT)
304 | BLT_BR00_32BPP_MASK(BLT_32BPP_MASK_ALPHA | BLT_32BPP_MASK_RGB)
305 | BLT_BR00_SRC_TILING_ENABLE(src_tiling_mode != I915_TILING_NONE)
306 | BLT_BR00_DST_TILING_ENABLE(dst_tiling_mode != I915_TILING_NONE)
307 | BLT_BR00_DWORD_LENGTH(GEN(batch, 8) ? 8 : 6),
308
309 BLT_BR13_CLIPPING_ENABLE(false)
310 | BLT_BR13_COLOR_DEPTH(BLT_COLOR_DEPTH_32BIT)
311 | BLT_BR13_RASTER_OPERATION(BLT_RASTER_OPERATION_SRC)
312 | BLT_BR13_DST_PITCH(dst_tiling_mode == I915_TILING_NONE
313 ? dst_pitch
314 : dst_pitch >> 2),
315
316 BLT_BR22_DST_Y1(dst_y) | BLT_BR22_DST_X1(dst_x),
317
318 BLT_BR23_DST_Y2(dst_y + height)
319 | BLT_BR23_DST_X2(dst_x + width));
320 intel_batch_add_dwords(batch, GEN(batch, 8) ? 2 : 1,
321 BLT_BR09_DST_ADDRESS(dst->offset64),
322 BLT_BR27_DST_ADDRESS_HI(dst->offset64 >> 32));
323 intel_batch_add_dwords(batch, 2,
324 BLT_BR26_SRC_Y1(src_y) | BLT_BR26_SRC_X1(src_x),
325 BLT_BR11_SRC_PITCH(src_tiling_mode == I915_TILING_NONE
326 ? src_pitch
327 : src_pitch >> 2));
328 intel_batch_add_dwords(batch, GEN(batch, 8) ? 2 : 1,
329 BLT_BR12_SRC_ADDRESS(src->offset64),
330 BLT_BR28_SRC_ADDRESS_HI(src->offset64 >> 32));
331}
332
333static inline void
334xy_color_blt(struct intel_batch *batch,
335 drm_intel_bo *dst, uint16_t dst_pitch,
336 uint16_t dst_x1, uint16_t dst_y1,
337 uint16_t dst_x2, uint16_t dst_y2,
338 uint32_t color)
339{
340 uint32_t tiling_mode, swizzle_mode;
341
342 intel_batch_ensure_space(batch, GEN(batch, 8) ? 7 : 6);
343
344 drm_intel_bo_get_tiling(dst, &tiling_mode, &swizzle_mode);
345
346 drm_intel_bo_emit_reloc_fence(batch->bo, intel_batch_offset(batch, 4), dst, 0,
347 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER);
348
349 intel_batch_add_dwords(batch, 4,
350 BLT_BR00_CLIENT(INTEL_CLIENT_BLT)
351 | BLT_BR00_OP(BLT_OP_XY_COLOR_BLT)
352 | BLT_BR00_32BPP_MASK(BLT_32BPP_MASK_ALPHA | BLT_32BPP_MASK_RGB)
353 | BLT_BR00_DST_TILING_ENABLE(tiling_mode != I915_TILING_NONE)
354 | BLT_BR00_DWORD_LENGTH(GEN(batch, 8) ? 5 : 4),
355
356 BLT_BR13_CLIPPING_ENABLE(false)
357 | BLT_BR13_COLOR_DEPTH(BLT_COLOR_DEPTH_32BIT)
358 | BLT_BR13_RASTER_OPERATION(BLT_RASTER_OPERATION_PAT)
359 | BLT_BR13_DST_PITCH(tiling_mode == I915_TILING_NONE
360 ? dst_pitch
361 : dst_pitch >> 2),
362
363 BLT_BR22_DST_Y1(dst_y1) | BLT_BR22_DST_X1(dst_x1),
364 BLT_BR23_DST_Y2(dst_y2) | BLT_BR23_DST_X2(dst_x2));
365 intel_batch_add_dwords(batch, GEN(batch, 8) ? 2 : 1,
366 BLT_BR09_DST_ADDRESS(dst->offset64),
367 BLT_BR27_DST_ADDRESS_HI(dst->offset64 >> 32));
368 intel_batch_add_dword(batch,
369 BLT_BR16_COLOR(color));
370}
371
372#endif