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