• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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