Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5564 | serge | 1 | /* |
2 | * Mesa 3-D graphics library |
||
3 | * |
||
4 | * Copyright (C) 2014 LunarG, Inc. |
||
5 | * |
||
6 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
7 | * copy of this software and associated documentation files (the "Software"), |
||
8 | * to deal in the Software without restriction, including without limitation |
||
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||
10 | * and/or sell copies of the Software, and to permit persons to whom the |
||
11 | * Software is furnished to do so, subject to the following conditions: |
||
12 | * |
||
13 | * The above copyright notice and this permission notice shall be included |
||
14 | * in all copies or substantial portions of the Software. |
||
15 | * |
||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||
21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||
22 | * DEALINGS IN THE SOFTWARE. |
||
23 | * |
||
24 | * Authors: |
||
25 | * Chia-I Wu |
||
26 | */ |
||
27 | |||
28 | #ifndef ILO_BUILDER_BLT_H |
||
29 | #define ILO_BUILDER_BLT_H |
||
30 | |||
31 | #include "genhw/genhw.h" |
||
32 | #include "intel_winsys.h" |
||
33 | |||
34 | #include "ilo_core.h" |
||
35 | #include "ilo_dev.h" |
||
36 | #include "ilo_builder.h" |
||
37 | |||
38 | enum gen6_blt_mask { |
||
39 | GEN6_BLT_MASK_8, |
||
40 | GEN6_BLT_MASK_16, |
||
41 | GEN6_BLT_MASK_32, |
||
42 | GEN6_BLT_MASK_32_LO, |
||
43 | GEN6_BLT_MASK_32_HI, |
||
44 | }; |
||
45 | |||
46 | struct gen6_blt_bo { |
||
47 | struct intel_bo *bo; |
||
48 | uint32_t offset; |
||
49 | int16_t pitch; |
||
50 | }; |
||
51 | |||
52 | struct gen6_blt_xy_bo { |
||
53 | struct intel_bo *bo; |
||
54 | uint32_t offset; |
||
55 | int16_t pitch; |
||
56 | |||
57 | enum gen_surface_tiling tiling; |
||
58 | int16_t x, y; |
||
59 | }; |
||
60 | |||
61 | /* |
||
62 | * From the Sandy Bridge PRM, volume 1 part 5, page 7: |
||
63 | * |
||
64 | * "The BLT engine is capable of transferring very large quantities of |
||
65 | * graphics data. Any graphics data read from and written to the |
||
66 | * destination is permitted to represent a number of pixels that occupies |
||
67 | * up to 65,536 scan lines and up to 32,768 bytes per scan line at the |
||
68 | * destination. The maximum number of pixels that may be represented per |
||
69 | * scan line's worth of graphics data depends on the color depth." |
||
70 | */ |
||
71 | static const int gen6_blt_max_bytes_per_scanline = 32768; |
||
72 | static const int gen6_blt_max_scanlines = 65536; |
||
73 | |||
74 | static inline uint32_t |
||
75 | gen6_blt_translate_value_mask(enum gen6_blt_mask value_mask) |
||
76 | { |
||
77 | switch (value_mask) { |
||
78 | case GEN6_BLT_MASK_8: return GEN6_BLITTER_BR13_FORMAT_8; |
||
79 | case GEN6_BLT_MASK_16: return GEN6_BLITTER_BR13_FORMAT_565; |
||
80 | default: return GEN6_BLITTER_BR13_FORMAT_8888; |
||
81 | } |
||
82 | } |
||
83 | |||
84 | static inline uint32_t |
||
85 | gen6_blt_translate_value_cpp(enum gen6_blt_mask value_mask) |
||
86 | { |
||
87 | switch (value_mask) { |
||
88 | case GEN6_BLT_MASK_8: return 1; |
||
89 | case GEN6_BLT_MASK_16: return 2; |
||
90 | default: return 4; |
||
91 | } |
||
92 | } |
||
93 | |||
94 | static inline uint32_t |
||
95 | gen6_blt_translate_write_mask(enum gen6_blt_mask write_mask) |
||
96 | { |
||
97 | switch (write_mask) { |
||
98 | case GEN6_BLT_MASK_32: return GEN6_BLITTER_BR00_WRITE_RGB | |
||
99 | GEN6_BLITTER_BR00_WRITE_A; |
||
100 | case GEN6_BLT_MASK_32_LO: return GEN6_BLITTER_BR00_WRITE_RGB; |
||
101 | case GEN6_BLT_MASK_32_HI: return GEN6_BLITTER_BR00_WRITE_A; |
||
102 | default: return 0; |
||
103 | } |
||
104 | } |
||
105 | |||
106 | static inline void |
||
107 | gen6_COLOR_BLT(struct ilo_builder *builder, |
||
108 | const struct gen6_blt_bo *dst, uint32_t pattern, |
||
109 | uint16_t width, uint16_t height, uint8_t rop, |
||
110 | enum gen6_blt_mask value_mask, |
||
111 | enum gen6_blt_mask write_mask) |
||
112 | { |
||
113 | const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 6 : 5; |
||
114 | const int cpp = gen6_blt_translate_value_cpp(value_mask); |
||
115 | uint32_t *dw; |
||
116 | unsigned pos; |
||
117 | |||
118 | ILO_DEV_ASSERT(builder->dev, 6, 8); |
||
119 | |||
120 | assert(width < gen6_blt_max_bytes_per_scanline); |
||
121 | assert(height < gen6_blt_max_scanlines); |
||
122 | /* offsets are naturally aligned and pitches are dword-aligned */ |
||
123 | assert(dst->offset % cpp == 0 && dst->pitch % 4 == 0); |
||
124 | |||
125 | pos = ilo_builder_batch_pointer(builder, cmd_len, &dw); |
||
126 | |||
127 | dw[0] = GEN6_BLITTER_CMD(COLOR_BLT) | |
||
128 | gen6_blt_translate_write_mask(write_mask) | |
||
129 | (cmd_len - 2); |
||
130 | dw[1] = rop << GEN6_BLITTER_BR13_ROP__SHIFT | |
||
131 | gen6_blt_translate_value_mask(value_mask) | |
||
132 | dst->pitch; |
||
133 | dw[2] = height << 16 | width; |
||
134 | |||
135 | if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) { |
||
136 | dw[5] = pattern; |
||
137 | |||
138 | ilo_builder_batch_reloc64(builder, pos + 3, |
||
139 | dst->bo, dst->offset, INTEL_RELOC_WRITE); |
||
140 | } else { |
||
141 | dw[4] = pattern; |
||
142 | |||
143 | ilo_builder_batch_reloc(builder, pos + 3, |
||
144 | dst->bo, dst->offset, INTEL_RELOC_WRITE); |
||
145 | } |
||
146 | } |
||
147 | |||
148 | static inline void |
||
149 | gen6_XY_COLOR_BLT(struct ilo_builder *builder, |
||
150 | const struct gen6_blt_xy_bo *dst, uint32_t pattern, |
||
151 | uint16_t width, uint16_t height, uint8_t rop, |
||
152 | enum gen6_blt_mask value_mask, |
||
153 | enum gen6_blt_mask write_mask) |
||
154 | { |
||
155 | const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 7 : 6; |
||
156 | const int cpp = gen6_blt_translate_value_cpp(value_mask); |
||
157 | int dst_align = 4, dst_pitch_shift = 0; |
||
158 | uint32_t *dw; |
||
159 | unsigned pos; |
||
160 | |||
161 | ILO_DEV_ASSERT(builder->dev, 6, 8); |
||
162 | |||
163 | assert(width * cpp < gen6_blt_max_bytes_per_scanline); |
||
164 | assert(height < gen6_blt_max_scanlines); |
||
165 | /* INT16_MAX */ |
||
166 | assert(dst->x + width <= 32767 && dst->y + height <= 32767); |
||
167 | |||
168 | pos = ilo_builder_batch_pointer(builder, cmd_len, &dw); |
||
169 | |||
170 | dw[0] = GEN6_BLITTER_CMD(XY_COLOR_BLT) | |
||
171 | gen6_blt_translate_write_mask(write_mask) | |
||
172 | (cmd_len - 2); |
||
173 | |||
174 | if (dst->tiling != GEN6_TILING_NONE) { |
||
175 | dw[0] |= GEN6_BLITTER_BR00_DST_TILED; |
||
176 | |||
177 | assert(dst->tiling == GEN6_TILING_X || dst->tiling == GEN6_TILING_Y); |
||
178 | dst_align = (dst->tiling == GEN6_TILING_Y) ? 128 : 512; |
||
179 | /* in dwords when tiled */ |
||
180 | dst_pitch_shift = 2; |
||
181 | } |
||
182 | |||
183 | assert(dst->offset % dst_align == 0 && dst->pitch % dst_align == 0); |
||
184 | |||
185 | dw[1] = rop << GEN6_BLITTER_BR13_ROP__SHIFT | |
||
186 | gen6_blt_translate_value_mask(value_mask) | |
||
187 | dst->pitch >> dst_pitch_shift; |
||
188 | dw[2] = dst->y << 16 | dst->x; |
||
189 | dw[3] = (dst->y + height) << 16 | (dst->x + width); |
||
190 | |||
191 | if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) { |
||
192 | dw[6] = pattern; |
||
193 | |||
194 | ilo_builder_batch_reloc64(builder, pos + 4, |
||
195 | dst->bo, dst->offset, INTEL_RELOC_WRITE); |
||
196 | } else { |
||
197 | dw[5] = pattern; |
||
198 | |||
199 | ilo_builder_batch_reloc(builder, pos + 4, |
||
200 | dst->bo, dst->offset, INTEL_RELOC_WRITE); |
||
201 | } |
||
202 | } |
||
203 | |||
204 | static inline void |
||
205 | gen6_SRC_COPY_BLT(struct ilo_builder *builder, |
||
206 | const struct gen6_blt_bo *dst, |
||
207 | const struct gen6_blt_bo *src, |
||
208 | uint16_t width, uint16_t height, uint8_t rop, |
||
209 | enum gen6_blt_mask value_mask, |
||
210 | enum gen6_blt_mask write_mask) |
||
211 | { |
||
212 | const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 8 : 6; |
||
213 | const int cpp = gen6_blt_translate_value_cpp(value_mask); |
||
214 | uint32_t *dw; |
||
215 | unsigned pos; |
||
216 | |||
217 | ILO_DEV_ASSERT(builder->dev, 6, 8); |
||
218 | |||
219 | assert(width < gen6_blt_max_bytes_per_scanline); |
||
220 | assert(height < gen6_blt_max_scanlines); |
||
221 | /* offsets are naturally aligned and pitches are dword-aligned */ |
||
222 | assert(dst->offset % cpp == 0 && dst->pitch % 4 == 0); |
||
223 | assert(src->offset % cpp == 0 && src->pitch % 4 == 0); |
||
224 | |||
225 | pos = ilo_builder_batch_pointer(builder, cmd_len, &dw); |
||
226 | |||
227 | dw[0] = GEN6_BLITTER_CMD(SRC_COPY_BLT) | |
||
228 | gen6_blt_translate_write_mask(write_mask) | |
||
229 | (cmd_len - 2); |
||
230 | dw[1] = rop << GEN6_BLITTER_BR13_ROP__SHIFT | |
||
231 | gen6_blt_translate_value_mask(value_mask) | |
||
232 | dst->pitch; |
||
233 | dw[2] = height << 16 | width; |
||
234 | |||
235 | if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) { |
||
236 | dw[5] = src->pitch; |
||
237 | |||
238 | ilo_builder_batch_reloc64(builder, pos + 3, |
||
239 | dst->bo, dst->offset, INTEL_RELOC_WRITE); |
||
240 | ilo_builder_batch_reloc64(builder, pos + 6, src->bo, src->offset, 0); |
||
241 | } else { |
||
242 | dw[4] = src->pitch; |
||
243 | |||
244 | ilo_builder_batch_reloc(builder, pos + 3, |
||
245 | dst->bo, dst->offset, INTEL_RELOC_WRITE); |
||
246 | ilo_builder_batch_reloc(builder, pos + 5, src->bo, src->offset, 0); |
||
247 | } |
||
248 | } |
||
249 | |||
250 | static inline void |
||
251 | gen6_XY_SRC_COPY_BLT(struct ilo_builder *builder, |
||
252 | const struct gen6_blt_xy_bo *dst, |
||
253 | const struct gen6_blt_xy_bo *src, |
||
254 | uint16_t width, uint16_t height, uint8_t rop, |
||
255 | enum gen6_blt_mask value_mask, |
||
256 | enum gen6_blt_mask write_mask) |
||
257 | { |
||
258 | const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 10 : 8; |
||
259 | const int cpp = gen6_blt_translate_value_cpp(value_mask); |
||
260 | int dst_align = 4, dst_pitch_shift = 0; |
||
261 | int src_align = 4, src_pitch_shift = 0; |
||
262 | uint32_t *dw; |
||
263 | unsigned pos; |
||
264 | |||
265 | ILO_DEV_ASSERT(builder->dev, 6, 8); |
||
266 | |||
267 | assert(width * cpp < gen6_blt_max_bytes_per_scanline); |
||
268 | assert(height < gen6_blt_max_scanlines); |
||
269 | /* INT16_MAX */ |
||
270 | assert(dst->x + width <= 32767 && dst->y + height <= 32767); |
||
271 | |||
272 | pos = ilo_builder_batch_pointer(builder, cmd_len, &dw); |
||
273 | |||
274 | dw[0] = GEN6_BLITTER_CMD(XY_SRC_COPY_BLT) | |
||
275 | gen6_blt_translate_write_mask(write_mask) | |
||
276 | (cmd_len - 2); |
||
277 | |||
278 | if (dst->tiling != GEN6_TILING_NONE) { |
||
279 | dw[0] |= GEN6_BLITTER_BR00_DST_TILED; |
||
280 | |||
281 | assert(dst->tiling == GEN6_TILING_X || dst->tiling == GEN6_TILING_Y); |
||
282 | dst_align = (dst->tiling == GEN6_TILING_Y) ? 128 : 512; |
||
283 | /* in dwords when tiled */ |
||
284 | dst_pitch_shift = 2; |
||
285 | } |
||
286 | |||
287 | if (src->tiling != GEN6_TILING_NONE) { |
||
288 | dw[0] |= GEN6_BLITTER_BR00_SRC_TILED; |
||
289 | |||
290 | assert(src->tiling == GEN6_TILING_X || src->tiling == GEN6_TILING_Y); |
||
291 | src_align = (src->tiling == GEN6_TILING_Y) ? 128 : 512; |
||
292 | /* in dwords when tiled */ |
||
293 | src_pitch_shift = 2; |
||
294 | } |
||
295 | |||
296 | assert(dst->offset % dst_align == 0 && dst->pitch % dst_align == 0); |
||
297 | assert(src->offset % src_align == 0 && src->pitch % src_align == 0); |
||
298 | |||
299 | dw[1] = rop << GEN6_BLITTER_BR13_ROP__SHIFT | |
||
300 | gen6_blt_translate_value_mask(value_mask) | |
||
301 | dst->pitch >> dst_pitch_shift; |
||
302 | dw[2] = dst->y << 16 | dst->x; |
||
303 | dw[3] = (dst->y + height) << 16 | (dst->x + width); |
||
304 | |||
305 | if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) { |
||
306 | dw[6] = src->y << 16 | src->x; |
||
307 | dw[7] = src->pitch >> src_pitch_shift; |
||
308 | |||
309 | ilo_builder_batch_reloc64(builder, pos + 4, |
||
310 | dst->bo, dst->offset, INTEL_RELOC_WRITE); |
||
311 | ilo_builder_batch_reloc64(builder, pos + 8, src->bo, src->offset, 0); |
||
312 | } else { |
||
313 | dw[5] = src->y << 16 | src->x; |
||
314 | dw[6] = src->pitch >> src_pitch_shift; |
||
315 | |||
316 | ilo_builder_batch_reloc(builder, pos + 4, |
||
317 | dst->bo, dst->offset, INTEL_RELOC_WRITE); |
||
318 | ilo_builder_batch_reloc(builder, pos + 7, src->bo, src->offset, 0); |
||
319 | } |
||
320 | } |
||
321 | |||
322 | #endif /* ILO_BUILDER_BLT_H */><>><>><>><>><>=>=>>>><>><>>>><>><>><>=>=>>>><>><>>> |