d0623db1472d306306de8c2fc0cbf9fbab48419a
[mesa.git] / src / gallium / drivers / etnaviv / etnaviv_translate.h
1 /*
2 * Copyright (c) 2012-2013 Etnaviv Project
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sub license,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the
12 * next paragraph) shall be included in all copies or substantial portions
13 * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23 /* inlined translation functions between gallium and vivante */
24 #ifndef H_TRANSLATE
25 #define H_TRANSLATE
26
27 #include "pipe/p_defines.h"
28 #include "pipe/p_format.h"
29 #include "pipe/p_state.h"
30
31 #include "etnaviv_debug.h"
32 #include "etnaviv_format.h"
33 #include "etnaviv_tiling.h"
34 #include "etnaviv_util.h"
35 #include "hw/cmdstream.xml.h"
36 #include "hw/state.xml.h"
37 #include "hw/state_3d.xml.h"
38
39 #include "util/u_format.h"
40
41 #include <stdio.h>
42
43 /* Returned when there is no match of pipe value to etna value */
44 #define ETNA_NO_MATCH (~0)
45
46 static inline uint32_t
47 translate_cull_face(unsigned cull_face, unsigned front_ccw)
48 {
49 switch (cull_face) {
50 case PIPE_FACE_NONE:
51 return VIVS_PA_CONFIG_CULL_FACE_MODE_OFF;
52 case PIPE_FACE_BACK:
53 return front_ccw ? VIVS_PA_CONFIG_CULL_FACE_MODE_CW
54 : VIVS_PA_CONFIG_CULL_FACE_MODE_CCW;
55 case PIPE_FACE_FRONT:
56 return front_ccw ? VIVS_PA_CONFIG_CULL_FACE_MODE_CCW
57 : VIVS_PA_CONFIG_CULL_FACE_MODE_CW;
58 default:
59 DBG("Unhandled cull face mode %i", cull_face);
60 return ETNA_NO_MATCH;
61 }
62 }
63
64 static inline uint32_t
65 translate_polygon_mode(unsigned polygon_mode)
66 {
67 switch (polygon_mode) {
68 case PIPE_POLYGON_MODE_FILL:
69 return VIVS_PA_CONFIG_FILL_MODE_SOLID;
70 case PIPE_POLYGON_MODE_LINE:
71 return VIVS_PA_CONFIG_FILL_MODE_WIREFRAME;
72 case PIPE_POLYGON_MODE_POINT:
73 return VIVS_PA_CONFIG_FILL_MODE_POINT;
74 default:
75 DBG("Unhandled polygon mode %i", polygon_mode);
76 return ETNA_NO_MATCH;
77 }
78 }
79
80 static inline uint32_t
81 translate_stencil_mode(bool enable_0, bool enable_1)
82 {
83 if (enable_0) {
84 return enable_1 ? VIVS_PE_STENCIL_CONFIG_MODE_TWO_SIDED
85 : VIVS_PE_STENCIL_CONFIG_MODE_ONE_SIDED;
86 } else {
87 return VIVS_PE_STENCIL_CONFIG_MODE_DISABLED;
88 }
89 }
90
91 static inline uint32_t
92 translate_stencil_op(unsigned stencil_op)
93 {
94 switch (stencil_op) {
95 case PIPE_STENCIL_OP_KEEP:
96 return STENCIL_OP_KEEP;
97 case PIPE_STENCIL_OP_ZERO:
98 return STENCIL_OP_ZERO;
99 case PIPE_STENCIL_OP_REPLACE:
100 return STENCIL_OP_REPLACE;
101 case PIPE_STENCIL_OP_INCR:
102 return STENCIL_OP_INCR;
103 case PIPE_STENCIL_OP_DECR:
104 return STENCIL_OP_DECR;
105 case PIPE_STENCIL_OP_INCR_WRAP:
106 return STENCIL_OP_INCR_WRAP;
107 case PIPE_STENCIL_OP_DECR_WRAP:
108 return STENCIL_OP_DECR_WRAP;
109 case PIPE_STENCIL_OP_INVERT:
110 return STENCIL_OP_INVERT;
111 default:
112 DBG("Unhandled stencil op: %i", stencil_op);
113 return ETNA_NO_MATCH;
114 }
115 }
116
117 static inline uint32_t
118 translate_blend(unsigned blend)
119 {
120 switch (blend) {
121 case PIPE_BLEND_ADD:
122 return BLEND_EQ_ADD;
123 case PIPE_BLEND_SUBTRACT:
124 return BLEND_EQ_SUBTRACT;
125 case PIPE_BLEND_REVERSE_SUBTRACT:
126 return BLEND_EQ_REVERSE_SUBTRACT;
127 case PIPE_BLEND_MIN:
128 return BLEND_EQ_MIN;
129 case PIPE_BLEND_MAX:
130 return BLEND_EQ_MAX;
131 default:
132 DBG("Unhandled blend: %i", blend);
133 return ETNA_NO_MATCH;
134 }
135 }
136
137 static inline uint32_t
138 translate_blend_factor(unsigned blend_factor)
139 {
140 switch (blend_factor) {
141 case PIPE_BLENDFACTOR_ONE:
142 return BLEND_FUNC_ONE;
143 case PIPE_BLENDFACTOR_SRC_COLOR:
144 return BLEND_FUNC_SRC_COLOR;
145 case PIPE_BLENDFACTOR_SRC_ALPHA:
146 return BLEND_FUNC_SRC_ALPHA;
147 case PIPE_BLENDFACTOR_DST_ALPHA:
148 return BLEND_FUNC_DST_ALPHA;
149 case PIPE_BLENDFACTOR_DST_COLOR:
150 return BLEND_FUNC_DST_COLOR;
151 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
152 return BLEND_FUNC_SRC_ALPHA_SATURATE;
153 case PIPE_BLENDFACTOR_CONST_COLOR:
154 return BLEND_FUNC_CONSTANT_COLOR;
155 case PIPE_BLENDFACTOR_CONST_ALPHA:
156 return BLEND_FUNC_CONSTANT_ALPHA;
157 case PIPE_BLENDFACTOR_ZERO:
158 return BLEND_FUNC_ZERO;
159 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
160 return BLEND_FUNC_ONE_MINUS_SRC_COLOR;
161 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
162 return BLEND_FUNC_ONE_MINUS_SRC_ALPHA;
163 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
164 return BLEND_FUNC_ONE_MINUS_DST_ALPHA;
165 case PIPE_BLENDFACTOR_INV_DST_COLOR:
166 return BLEND_FUNC_ONE_MINUS_DST_COLOR;
167 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
168 return BLEND_FUNC_ONE_MINUS_CONSTANT_COLOR;
169 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
170 return BLEND_FUNC_ONE_MINUS_CONSTANT_ALPHA;
171 case PIPE_BLENDFACTOR_SRC1_COLOR:
172 case PIPE_BLENDFACTOR_SRC1_ALPHA:
173 case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
174 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
175 default:
176 DBG("Unhandled blend factor: %i", blend_factor);
177 return ETNA_NO_MATCH;
178 }
179 }
180
181 static inline uint32_t
182 translate_texture_wrapmode(unsigned wrap)
183 {
184 switch (wrap) {
185 case PIPE_TEX_WRAP_REPEAT:
186 return TEXTURE_WRAPMODE_REPEAT;
187 case PIPE_TEX_WRAP_CLAMP:
188 return TEXTURE_WRAPMODE_CLAMP_TO_EDGE;
189 case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
190 return TEXTURE_WRAPMODE_CLAMP_TO_EDGE;
191 case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
192 return TEXTURE_WRAPMODE_CLAMP_TO_EDGE; /* XXX */
193 case PIPE_TEX_WRAP_MIRROR_REPEAT:
194 return TEXTURE_WRAPMODE_MIRRORED_REPEAT;
195 case PIPE_TEX_WRAP_MIRROR_CLAMP:
196 return TEXTURE_WRAPMODE_MIRRORED_REPEAT; /* XXX */
197 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
198 return TEXTURE_WRAPMODE_MIRRORED_REPEAT; /* XXX */
199 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
200 return TEXTURE_WRAPMODE_MIRRORED_REPEAT; /* XXX */
201 default:
202 DBG("Unhandled texture wrapmode: %i", wrap);
203 return ETNA_NO_MATCH;
204 }
205 }
206
207 static inline uint32_t
208 translate_texture_mipfilter(unsigned filter)
209 {
210 switch (filter) {
211 case PIPE_TEX_MIPFILTER_NEAREST:
212 return TEXTURE_FILTER_NEAREST;
213 case PIPE_TEX_MIPFILTER_LINEAR:
214 return TEXTURE_FILTER_LINEAR;
215 case PIPE_TEX_MIPFILTER_NONE:
216 return TEXTURE_FILTER_NONE;
217 default:
218 DBG("Unhandled texture mipfilter: %i", filter);
219 return ETNA_NO_MATCH;
220 }
221 }
222
223 static inline uint32_t
224 translate_texture_filter(unsigned filter)
225 {
226 switch (filter) {
227 case PIPE_TEX_FILTER_NEAREST:
228 return TEXTURE_FILTER_NEAREST;
229 case PIPE_TEX_FILTER_LINEAR:
230 return TEXTURE_FILTER_LINEAR;
231 /* What about anisotropic? */
232 default:
233 DBG("Unhandled texture filter: %i", filter);
234 return ETNA_NO_MATCH;
235 }
236 }
237
238 /* return a RS "compatible" format for use when copying */
239 static inline enum pipe_format
240 etna_compatible_rs_format(enum pipe_format fmt)
241 {
242 /* YUYV and UYVY are blocksize 4, but 2 bytes per pixel */
243 if (fmt == PIPE_FORMAT_YUYV || fmt == PIPE_FORMAT_UYVY)
244 return PIPE_FORMAT_B4G4R4A4_UNORM;
245
246 switch (util_format_get_blocksize(fmt)) {
247 case 2:
248 return PIPE_FORMAT_B4G4R4A4_UNORM;
249 case 4:
250 return PIPE_FORMAT_B8G8R8A8_UNORM;
251 default:
252 return fmt;
253 }
254 }
255
256 static inline int
257 translate_rb_src_dst_swap(enum pipe_format src, enum pipe_format dst)
258 {
259 return translate_rs_format_rb_swap(src) ^ translate_rs_format_rb_swap(dst);
260 }
261
262 static inline uint32_t
263 translate_depth_format(enum pipe_format fmt)
264 {
265 /* Note: Pipe format convention is LSB to MSB, VIVS is MSB to LSB */
266 switch (fmt) {
267 case PIPE_FORMAT_Z16_UNORM:
268 return VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D16;
269 case PIPE_FORMAT_X8Z24_UNORM:
270 return VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D24S8;
271 case PIPE_FORMAT_S8_UINT_Z24_UNORM:
272 return VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D24S8;
273 default:
274 return ETNA_NO_MATCH;
275 }
276 }
277
278 /* render target format for MSAA */
279 static inline uint32_t
280 translate_msaa_format(enum pipe_format fmt)
281 {
282 /* Note: Pipe format convention is LSB to MSB, VIVS is MSB to LSB */
283 switch (fmt) {
284 case PIPE_FORMAT_B4G4R4X4_UNORM:
285 return VIVS_TS_MEM_CONFIG_MSAA_FORMAT_A4R4G4B4;
286 case PIPE_FORMAT_B4G4R4A4_UNORM:
287 return VIVS_TS_MEM_CONFIG_MSAA_FORMAT_A4R4G4B4;
288 case PIPE_FORMAT_B5G5R5X1_UNORM:
289 return VIVS_TS_MEM_CONFIG_MSAA_FORMAT_A1R5G5B5;
290 case PIPE_FORMAT_B5G5R5A1_UNORM:
291 return VIVS_TS_MEM_CONFIG_MSAA_FORMAT_A1R5G5B5;
292 case PIPE_FORMAT_B5G6R5_UNORM:
293 return VIVS_TS_MEM_CONFIG_MSAA_FORMAT_R5G6B5;
294 case PIPE_FORMAT_B8G8R8X8_UNORM:
295 return VIVS_TS_MEM_CONFIG_MSAA_FORMAT_X8R8G8B8;
296 case PIPE_FORMAT_B8G8R8A8_UNORM:
297 return VIVS_TS_MEM_CONFIG_MSAA_FORMAT_A8R8G8B8;
298 /* MSAA with YUYV not supported */
299 default:
300 return ETNA_NO_MATCH;
301 }
302 }
303
304 /* Return normalization flag for vertex element format */
305 static inline uint32_t
306 translate_vertex_format_normalize(enum pipe_format fmt)
307 {
308 const struct util_format_description *desc = util_format_description(fmt);
309 if (!desc)
310 return VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF;
311
312 /* assumes that normalization of channel 0 holds for all channels;
313 * this holds for all vertex formats that we support */
314 return desc->channel[0].normalized
315 ? VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_ON
316 : VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF;
317 }
318
319 static inline uint32_t
320 translate_index_size(unsigned index_size)
321 {
322 switch (index_size) {
323 case 1:
324 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_CHAR;
325 case 2:
326 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_SHORT;
327 case 4:
328 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_INT;
329 default:
330 DBG("Unhandled index size %i", index_size);
331 return ETNA_NO_MATCH;
332 }
333 }
334
335 static inline uint32_t
336 translate_draw_mode(unsigned mode)
337 {
338 switch (mode) {
339 case PIPE_PRIM_POINTS:
340 return PRIMITIVE_TYPE_POINTS;
341 case PIPE_PRIM_LINES:
342 return PRIMITIVE_TYPE_LINES;
343 case PIPE_PRIM_LINE_LOOP:
344 return PRIMITIVE_TYPE_LINE_LOOP;
345 case PIPE_PRIM_LINE_STRIP:
346 return PRIMITIVE_TYPE_LINE_STRIP;
347 case PIPE_PRIM_TRIANGLES:
348 return PRIMITIVE_TYPE_TRIANGLES;
349 case PIPE_PRIM_TRIANGLE_STRIP:
350 return PRIMITIVE_TYPE_TRIANGLE_STRIP;
351 case PIPE_PRIM_TRIANGLE_FAN:
352 return PRIMITIVE_TYPE_TRIANGLE_FAN;
353 case PIPE_PRIM_QUADS:
354 return PRIMITIVE_TYPE_QUADS;
355 default:
356 DBG("Unhandled draw mode primitive %i", mode);
357 return ETNA_NO_MATCH;
358 }
359 }
360
361 /* Get size multiple for size of texture/rendertarget with a certain layout
362 * This is affected by many different parameters:
363 * - A horizontal multiple of 16 is used when possible as resolve can be used
364 * at the cost of only a little bit extra memory usage.
365 * - If the surface is to be used with the resolve engine, set rs_align true.
366 * If set, a horizontal multiple of 16 will be used for tiled and linear,
367 * otherwise one of 16. However, such a surface will be incompatible
368 * with the samplers if the GPU does hot support the HALIGN feature.
369 * - If the surface is supertiled, horizontal and vertical multiple is always 64
370 * - If the surface is multi tiled or supertiled, make sure that the vertical size
371 * is a multiple of the number of pixel pipes as well.
372 * */
373 static inline void
374 etna_layout_multiple(unsigned layout, unsigned pixel_pipes, bool rs_align,
375 unsigned *paddingX, unsigned *paddingY, unsigned *halign)
376 {
377 switch (layout) {
378 case ETNA_LAYOUT_LINEAR:
379 *paddingX = rs_align ? 16 : 4;
380 *paddingY = 1;
381 *halign = rs_align ? TEXTURE_HALIGN_SIXTEEN : TEXTURE_HALIGN_FOUR;
382 break;
383 case ETNA_LAYOUT_TILED:
384 *paddingX = rs_align ? 16 : 4;
385 *paddingY = 4;
386 *halign = rs_align ? TEXTURE_HALIGN_SIXTEEN : TEXTURE_HALIGN_FOUR;
387 break;
388 case ETNA_LAYOUT_SUPER_TILED:
389 *paddingX = 64;
390 *paddingY = 64;
391 *halign = TEXTURE_HALIGN_SUPER_TILED;
392 break;
393 case ETNA_LAYOUT_MULTI_TILED:
394 *paddingX = 16;
395 *paddingY = 4 * pixel_pipes;
396 *halign = TEXTURE_HALIGN_SPLIT_TILED;
397 break;
398 case ETNA_LAYOUT_MULTI_SUPERTILED:
399 *paddingX = 64;
400 *paddingY = 64 * pixel_pipes;
401 *halign = TEXTURE_HALIGN_SPLIT_SUPER_TILED;
402 break;
403 default:
404 DBG("Unhandled layout %i", layout);
405 }
406 }
407
408 /* return 32-bit clear pattern for color */
409 static inline uint32_t
410 translate_clear_color(enum pipe_format format,
411 const union pipe_color_union *color)
412 {
413 uint32_t clear_value = 0;
414
415 // XXX util_pack_color
416 switch (format) {
417 case PIPE_FORMAT_B8G8R8A8_UNORM:
418 case PIPE_FORMAT_B8G8R8X8_UNORM:
419 clear_value = etna_cfloat_to_uintN(color->f[2], 8) |
420 (etna_cfloat_to_uintN(color->f[1], 8) << 8) |
421 (etna_cfloat_to_uintN(color->f[0], 8) << 16) |
422 (etna_cfloat_to_uintN(color->f[3], 8) << 24);
423 break;
424 case PIPE_FORMAT_B4G4R4X4_UNORM:
425 case PIPE_FORMAT_B4G4R4A4_UNORM:
426 clear_value = etna_cfloat_to_uintN(color->f[2], 4) |
427 (etna_cfloat_to_uintN(color->f[1], 4) << 4) |
428 (etna_cfloat_to_uintN(color->f[0], 4) << 8) |
429 (etna_cfloat_to_uintN(color->f[3], 4) << 12);
430 clear_value |= clear_value << 16;
431 break;
432 case PIPE_FORMAT_B5G5R5X1_UNORM:
433 case PIPE_FORMAT_B5G5R5A1_UNORM:
434 clear_value = etna_cfloat_to_uintN(color->f[2], 5) |
435 (etna_cfloat_to_uintN(color->f[1], 5) << 5) |
436 (etna_cfloat_to_uintN(color->f[0], 5) << 10) |
437 (etna_cfloat_to_uintN(color->f[3], 1) << 15);
438 clear_value |= clear_value << 16;
439 break;
440 case PIPE_FORMAT_B5G6R5_UNORM:
441 clear_value = etna_cfloat_to_uintN(color->f[2], 5) |
442 (etna_cfloat_to_uintN(color->f[1], 6) << 5) |
443 (etna_cfloat_to_uintN(color->f[0], 5) << 11);
444 clear_value |= clear_value << 16;
445 break;
446 default:
447 DBG("Unhandled pipe format for color clear: %i", format);
448 }
449
450 return clear_value;
451 }
452
453 static inline uint32_t
454 translate_clear_depth_stencil(enum pipe_format format, float depth,
455 unsigned stencil)
456 {
457 uint32_t clear_value = 0;
458
459 // XXX util_pack_color
460 switch (format) {
461 case PIPE_FORMAT_Z16_UNORM:
462 clear_value = etna_cfloat_to_uintN(depth, 16);
463 clear_value |= clear_value << 16;
464 break;
465 case PIPE_FORMAT_X8Z24_UNORM:
466 case PIPE_FORMAT_S8_UINT_Z24_UNORM:
467 clear_value = (etna_cfloat_to_uintN(depth, 24) << 8) | (stencil & 0xFF);
468 break;
469 default:
470 DBG("Unhandled pipe format for depth stencil clear: %i", format);
471 }
472 return clear_value;
473 }
474
475 /* Convert MSAA number of samples to x and y scaling factor and
476 * VIVS_GL_MULTI_SAMPLE_CONFIG value.
477 * Return true if supported and false otherwise. */
478 static inline bool
479 translate_samples_to_xyscale(int num_samples, int *xscale_out, int *yscale_out,
480 uint32_t *config_out)
481 {
482 int xscale, yscale;
483 uint32_t config;
484
485 switch (num_samples) {
486 case 0:
487 case 1:
488 xscale = 1;
489 yscale = 1;
490 config = VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_NONE;
491 break;
492 case 2:
493 xscale = 2;
494 yscale = 1;
495 config = VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_2X;
496 break;
497 case 4:
498 xscale = 2;
499 yscale = 2;
500 config = VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_4X;
501 break;
502 default:
503 return false;
504 }
505
506 if (xscale_out)
507 *xscale_out = xscale;
508 if (yscale_out)
509 *yscale_out = yscale;
510 if (config_out)
511 *config_out = config;
512
513 return true;
514 }
515
516 #endif