• 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    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