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_util.h"
34 #include "hw/cmdstream.xml.h"
35 #include "hw/common_3d.xml.h"
36 #include "hw/state.xml.h"
37 #include "hw/state_3d.xml.h"
38
39 #include "util/format/u_format.h"
40 #include "util/u_math.h"
41
42 /* Returned when there is no match of pipe value to etna value */
43 #define ETNA_NO_MATCH (~0)
44
45 static inline uint32_t
translate_cull_face(unsigned cull_face,unsigned front_ccw)46 translate_cull_face(unsigned cull_face, unsigned front_ccw)
47 {
48 switch (cull_face) {
49 case PIPE_FACE_NONE:
50 case PIPE_FACE_FRONT_AND_BACK: /* handled in draw_vbo */
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
translate_polygon_mode(unsigned polygon_mode)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
translate_stencil_mode(bool enable_0,bool enable_1)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
translate_stencil_op(unsigned stencil_op)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
translate_blend_factor(unsigned blend_factor)118 translate_blend_factor(unsigned blend_factor)
119 {
120 switch (blend_factor) {
121 case PIPE_BLENDFACTOR_ONE:
122 return BLEND_FUNC_ONE;
123 case PIPE_BLENDFACTOR_SRC_COLOR:
124 return BLEND_FUNC_SRC_COLOR;
125 case PIPE_BLENDFACTOR_SRC_ALPHA:
126 return BLEND_FUNC_SRC_ALPHA;
127 case PIPE_BLENDFACTOR_DST_ALPHA:
128 return BLEND_FUNC_DST_ALPHA;
129 case PIPE_BLENDFACTOR_DST_COLOR:
130 return BLEND_FUNC_DST_COLOR;
131 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
132 return BLEND_FUNC_SRC_ALPHA_SATURATE;
133 case PIPE_BLENDFACTOR_CONST_COLOR:
134 return BLEND_FUNC_CONSTANT_COLOR;
135 case PIPE_BLENDFACTOR_CONST_ALPHA:
136 return BLEND_FUNC_CONSTANT_ALPHA;
137 case PIPE_BLENDFACTOR_ZERO:
138 return BLEND_FUNC_ZERO;
139 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
140 return BLEND_FUNC_ONE_MINUS_SRC_COLOR;
141 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
142 return BLEND_FUNC_ONE_MINUS_SRC_ALPHA;
143 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
144 return BLEND_FUNC_ONE_MINUS_DST_ALPHA;
145 case PIPE_BLENDFACTOR_INV_DST_COLOR:
146 return BLEND_FUNC_ONE_MINUS_DST_COLOR;
147 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
148 return BLEND_FUNC_ONE_MINUS_CONSTANT_COLOR;
149 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
150 return BLEND_FUNC_ONE_MINUS_CONSTANT_ALPHA;
151 case PIPE_BLENDFACTOR_SRC1_COLOR:
152 case PIPE_BLENDFACTOR_SRC1_ALPHA:
153 case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
154 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
155 default:
156 DBG("Unhandled blend factor: %i", blend_factor);
157 return ETNA_NO_MATCH;
158 }
159 }
160
161 static inline uint32_t
translate_texture_wrapmode(unsigned wrap)162 translate_texture_wrapmode(unsigned wrap)
163 {
164 switch (wrap) {
165 case PIPE_TEX_WRAP_REPEAT:
166 return TEXTURE_WRAPMODE_REPEAT;
167 case PIPE_TEX_WRAP_CLAMP:
168 return TEXTURE_WRAPMODE_CLAMP_TO_EDGE;
169 case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
170 return TEXTURE_WRAPMODE_CLAMP_TO_EDGE;
171 case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
172 return TEXTURE_WRAPMODE_CLAMP_TO_EDGE; /* XXX */
173 case PIPE_TEX_WRAP_MIRROR_REPEAT:
174 return TEXTURE_WRAPMODE_MIRRORED_REPEAT;
175 case PIPE_TEX_WRAP_MIRROR_CLAMP:
176 return TEXTURE_WRAPMODE_MIRRORED_REPEAT; /* XXX */
177 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
178 return TEXTURE_WRAPMODE_MIRRORED_REPEAT; /* XXX */
179 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
180 return TEXTURE_WRAPMODE_MIRRORED_REPEAT; /* XXX */
181 default:
182 DBG("Unhandled texture wrapmode: %i", wrap);
183 return ETNA_NO_MATCH;
184 }
185 }
186
187 static inline uint32_t
translate_texture_mipfilter(unsigned filter)188 translate_texture_mipfilter(unsigned filter)
189 {
190 switch (filter) {
191 case PIPE_TEX_MIPFILTER_NEAREST:
192 return TEXTURE_FILTER_NEAREST;
193 case PIPE_TEX_MIPFILTER_LINEAR:
194 return TEXTURE_FILTER_LINEAR;
195 case PIPE_TEX_MIPFILTER_NONE:
196 return TEXTURE_FILTER_NONE;
197 default:
198 DBG("Unhandled texture mipfilter: %i", filter);
199 return ETNA_NO_MATCH;
200 }
201 }
202
203 static inline uint32_t
translate_texture_filter(unsigned filter)204 translate_texture_filter(unsigned filter)
205 {
206 switch (filter) {
207 case PIPE_TEX_FILTER_NEAREST:
208 return TEXTURE_FILTER_NEAREST;
209 case PIPE_TEX_FILTER_LINEAR:
210 return TEXTURE_FILTER_LINEAR;
211 default:
212 DBG("Unhandled texture filter: %i", filter);
213 return ETNA_NO_MATCH;
214 }
215 }
216
217 static inline int
translate_rb_src_dst_swap(enum pipe_format src,enum pipe_format dst)218 translate_rb_src_dst_swap(enum pipe_format src, enum pipe_format dst)
219 {
220 return translate_pe_format_rb_swap(src) ^ translate_pe_format_rb_swap(dst);
221 }
222
223 static inline uint32_t
translate_depth_format(enum pipe_format fmt)224 translate_depth_format(enum pipe_format fmt)
225 {
226 /* Note: Pipe format convention is LSB to MSB, VIVS is MSB to LSB */
227 switch (fmt) {
228 case PIPE_FORMAT_Z16_UNORM:
229 return VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D16;
230 case PIPE_FORMAT_X8Z24_UNORM:
231 return VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D24S8;
232 case PIPE_FORMAT_S8_UINT_Z24_UNORM:
233 return VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D24S8;
234 default:
235 return ETNA_NO_MATCH;
236 }
237 }
238
239 /* render target format for MSAA */
240 static inline uint32_t
translate_ts_format(enum pipe_format fmt)241 translate_ts_format(enum pipe_format fmt)
242 {
243 /* Note: Pipe format convention is LSB to MSB, VIVS is MSB to LSB */
244 switch (fmt) {
245 case PIPE_FORMAT_B4G4R4X4_UNORM:
246 case PIPE_FORMAT_B4G4R4A4_UNORM:
247 return COMPRESSION_FORMAT_A4R4G4B4;
248 case PIPE_FORMAT_B5G5R5X1_UNORM:
249 return COMPRESSION_FORMAT_A1R5G5B5;
250 case PIPE_FORMAT_B5G5R5A1_UNORM:
251 return COMPRESSION_FORMAT_A1R5G5B5;
252 case PIPE_FORMAT_B5G6R5_UNORM:
253 return COMPRESSION_FORMAT_R5G6B5;
254 case PIPE_FORMAT_B8G8R8X8_UNORM:
255 case PIPE_FORMAT_B8G8R8X8_SRGB:
256 case PIPE_FORMAT_R8G8B8X8_UNORM:
257 return COMPRESSION_FORMAT_X8R8G8B8;
258 case PIPE_FORMAT_B8G8R8A8_UNORM:
259 case PIPE_FORMAT_B8G8R8A8_SRGB:
260 case PIPE_FORMAT_R8G8B8A8_UNORM:
261 return COMPRESSION_FORMAT_A8R8G8B8;
262 case PIPE_FORMAT_S8_UINT_Z24_UNORM:
263 return COMPRESSION_FORMAT_D24S8;
264 case PIPE_FORMAT_X8Z24_UNORM:
265 return COMPRESSION_FORMAT_D24X8;
266 case PIPE_FORMAT_Z16_UNORM:
267 return COMPRESSION_FORMAT_D16;
268 /* MSAA with YUYV not supported */
269 default:
270 return ETNA_NO_MATCH;
271 }
272 }
273
274 /* Return normalization flag for vertex element format */
275 static inline uint32_t
translate_vertex_format_normalize(enum pipe_format fmt)276 translate_vertex_format_normalize(enum pipe_format fmt)
277 {
278 const struct util_format_description *desc = util_format_description(fmt);
279
280 /* assumes that normalization of channel 0 holds for all channels;
281 * this holds for all vertex formats that we support */
282 return desc->channel[0].normalized
283 ? VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_SIGN_EXTEND
284 : VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF;
285 }
286
287 static inline uint32_t
translate_output_mode(enum pipe_format fmt,bool halti5)288 translate_output_mode(enum pipe_format fmt, bool halti5)
289 {
290 const unsigned bits =
291 util_format_get_component_bits(fmt, UTIL_FORMAT_COLORSPACE_RGB, 0);
292
293 if (bits == 32)
294 return COLOR_OUTPUT_MODE_UIF32;
295
296 if (!util_format_is_pure_integer(fmt))
297 return COLOR_OUTPUT_MODE_NORMAL;
298
299 /* generic integer output mode pre-halti5 (?) */
300 if (bits == 10 || !halti5)
301 return COLOR_OUTPUT_MODE_A2B10G10R10UI;
302
303 if (util_format_is_pure_sint(fmt))
304 return bits == 8 ? COLOR_OUTPUT_MODE_I8 : COLOR_OUTPUT_MODE_I16;
305
306 return bits == 8 ? COLOR_OUTPUT_MODE_U8 : COLOR_OUTPUT_MODE_U16;
307 }
308
309 static inline uint32_t
translate_index_size(unsigned index_size)310 translate_index_size(unsigned index_size)
311 {
312 switch (index_size) {
313 case 1:
314 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_CHAR;
315 case 2:
316 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_SHORT;
317 case 4:
318 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_INT;
319 default:
320 DBG("Unhandled index size %i", index_size);
321 return ETNA_NO_MATCH;
322 }
323 }
324
325 static inline uint32_t
translate_draw_mode(unsigned mode)326 translate_draw_mode(unsigned mode)
327 {
328 switch (mode) {
329 case PIPE_PRIM_POINTS:
330 return PRIMITIVE_TYPE_POINTS;
331 case PIPE_PRIM_LINES:
332 return PRIMITIVE_TYPE_LINES;
333 case PIPE_PRIM_LINE_LOOP:
334 return PRIMITIVE_TYPE_LINE_LOOP;
335 case PIPE_PRIM_LINE_STRIP:
336 return PRIMITIVE_TYPE_LINE_STRIP;
337 case PIPE_PRIM_TRIANGLES:
338 return PRIMITIVE_TYPE_TRIANGLES;
339 case PIPE_PRIM_TRIANGLE_STRIP:
340 return PRIMITIVE_TYPE_TRIANGLE_STRIP;
341 case PIPE_PRIM_TRIANGLE_FAN:
342 return PRIMITIVE_TYPE_TRIANGLE_FAN;
343 case PIPE_PRIM_QUADS:
344 return PRIMITIVE_TYPE_QUADS;
345 default:
346 DBG("Unhandled draw mode primitive %i", mode);
347 return ETNA_NO_MATCH;
348 }
349 }
350
351 /* Get size multiple for size of texture/rendertarget with a certain layout
352 * This is affected by many different parameters:
353 * - A horizontal multiple of 16 is used when possible as resolve can be used
354 * at the cost of only a little bit extra memory usage.
355 * - If the surface is to be used with the resolve engine, set rs_align true.
356 * If set, a horizontal multiple of 16 will be used for tiled and linear,
357 * otherwise one of 16. However, such a surface will be incompatible
358 * with the samplers if the GPU does hot support the HALIGN feature.
359 * - If the surface is supertiled, horizontal and vertical multiple is always 64
360 * - If the surface is multi tiled or supertiled, make sure that the vertical size
361 * is a multiple of the number of pixel pipes as well.
362 * */
363 static inline void
etna_layout_multiple(unsigned layout,unsigned pixel_pipes,bool rs_align,unsigned * paddingX,unsigned * paddingY,unsigned * halign)364 etna_layout_multiple(unsigned layout, unsigned pixel_pipes, bool rs_align,
365 unsigned *paddingX, unsigned *paddingY, unsigned *halign)
366 {
367 switch (layout) {
368 case ETNA_LAYOUT_LINEAR:
369 *paddingX = rs_align ? 16 : 4;
370 *paddingY = 1;
371 *halign = rs_align ? TEXTURE_HALIGN_SIXTEEN : TEXTURE_HALIGN_FOUR;
372 break;
373 case ETNA_LAYOUT_TILED:
374 *paddingX = rs_align ? 16 : 4;
375 *paddingY = 4;
376 *halign = rs_align ? TEXTURE_HALIGN_SIXTEEN : TEXTURE_HALIGN_FOUR;
377 break;
378 case ETNA_LAYOUT_SUPER_TILED:
379 *paddingX = 64;
380 *paddingY = 64;
381 *halign = TEXTURE_HALIGN_SUPER_TILED;
382 break;
383 case ETNA_LAYOUT_MULTI_TILED:
384 *paddingX = 16;
385 *paddingY = 4 * pixel_pipes;
386 *halign = TEXTURE_HALIGN_SPLIT_TILED;
387 break;
388 case ETNA_LAYOUT_MULTI_SUPERTILED:
389 *paddingX = 64;
390 *paddingY = 64 * pixel_pipes;
391 *halign = TEXTURE_HALIGN_SPLIT_SUPER_TILED;
392 break;
393 default:
394 DBG("Unhandled layout %i", layout);
395 }
396 }
397
398 static inline uint32_t
translate_clear_depth_stencil(enum pipe_format format,float depth,unsigned stencil)399 translate_clear_depth_stencil(enum pipe_format format, float depth,
400 unsigned stencil)
401 {
402 uint32_t clear_value = 0;
403
404 // XXX util_pack_color
405 switch (format) {
406 case PIPE_FORMAT_Z16_UNORM:
407 clear_value = etna_cfloat_to_uintN(depth, 16);
408 clear_value |= clear_value << 16;
409 break;
410 case PIPE_FORMAT_X8Z24_UNORM:
411 case PIPE_FORMAT_S8_UINT_Z24_UNORM:
412 clear_value = (etna_cfloat_to_uintN(depth, 24) << 8) | (stencil & 0xFF);
413 break;
414 default:
415 DBG("Unhandled pipe format for depth stencil clear: %i", format);
416 }
417 return clear_value;
418 }
419
420 /* Convert MSAA number of samples to x and y scaling factor.
421 * Return true if supported and false otherwise. */
422 static inline bool
translate_samples_to_xyscale(int num_samples,int * xscale_out,int * yscale_out)423 translate_samples_to_xyscale(int num_samples, int *xscale_out, int *yscale_out)
424 {
425 int xscale, yscale;
426
427 switch (num_samples) {
428 case 0:
429 case 1:
430 xscale = 1;
431 yscale = 1;
432 break;
433 case 2:
434 xscale = 2;
435 yscale = 1;
436 break;
437 case 4:
438 xscale = 2;
439 yscale = 2;
440 break;
441 default:
442 return false;
443 }
444
445 if (xscale_out)
446 *xscale_out = xscale;
447 if (yscale_out)
448 *yscale_out = yscale;
449
450 return true;
451 }
452
453 static inline uint32_t
translate_texture_target(unsigned target)454 translate_texture_target(unsigned target)
455 {
456 switch (target) {
457 case PIPE_TEXTURE_1D:
458 return TEXTURE_TYPE_1D;
459 case PIPE_TEXTURE_2D:
460 case PIPE_TEXTURE_RECT:
461 case PIPE_TEXTURE_1D_ARRAY:
462 return TEXTURE_TYPE_2D;
463 case PIPE_TEXTURE_CUBE:
464 return TEXTURE_TYPE_CUBE_MAP;
465 case PIPE_TEXTURE_3D:
466 case PIPE_TEXTURE_2D_ARRAY:
467 return TEXTURE_TYPE_3D;
468 default:
469 DBG("Unhandled texture target: %i", target);
470 return ETNA_NO_MATCH;
471 }
472 }
473
474 static inline uint32_t
translate_texture_compare(enum pipe_compare_func compare_func)475 translate_texture_compare(enum pipe_compare_func compare_func)
476 {
477 switch (compare_func) {
478 case PIPE_FUNC_NEVER:
479 return TEXTURE_COMPARE_FUNC_NEVER;
480 case PIPE_FUNC_LESS:
481 return TEXTURE_COMPARE_FUNC_LESS;
482 case PIPE_FUNC_EQUAL:
483 return TEXTURE_COMPARE_FUNC_EQUAL;
484 case PIPE_FUNC_LEQUAL:
485 return TEXTURE_COMPARE_FUNC_LEQUAL;
486 case PIPE_FUNC_GREATER:
487 return TEXTURE_COMPARE_FUNC_GREATER;
488 case PIPE_FUNC_NOTEQUAL:
489 return TEXTURE_COMPARE_FUNC_NOTEQUAL;
490 case PIPE_FUNC_GEQUAL:
491 return TEXTURE_COMPARE_FUNC_GEQUAL;
492 case PIPE_FUNC_ALWAYS:
493 return TEXTURE_COMPARE_FUNC_ALWAYS;
494 default:
495 unreachable("Invalid compare func");
496 }
497 }
498
499 #endif
500