main neuwld / intel / blt.h
  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