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