2 * Copyright (c) 2012-2013 Etnaviv Project
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:
11 * The above copyright notice and this permission notice (including the
12 * next paragraph) shall be included in all copies or substantial portions
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.
23 /* inlined translation functions between gallium and vivante */
27 #include "pipe/p_defines.h"
28 #include "pipe/p_format.h"
29 #include "pipe/p_state.h"
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"
40 #include "util/u_format.h"
41 #include "util/u_math.h"
45 /* Returned when there is no match of pipe value to etna value */
46 #define ETNA_NO_MATCH (~0)
48 static inline uint32_t
49 translate_cull_face(unsigned cull_face
, unsigned front_ccw
)
53 return VIVS_PA_CONFIG_CULL_FACE_MODE_OFF
;
55 return front_ccw
? VIVS_PA_CONFIG_CULL_FACE_MODE_CW
56 : VIVS_PA_CONFIG_CULL_FACE_MODE_CCW
;
58 return front_ccw
? VIVS_PA_CONFIG_CULL_FACE_MODE_CCW
59 : VIVS_PA_CONFIG_CULL_FACE_MODE_CW
;
61 DBG("Unhandled cull face mode %i", cull_face
);
66 static inline uint32_t
67 translate_polygon_mode(unsigned polygon_mode
)
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
;
77 DBG("Unhandled polygon mode %i", polygon_mode
);
82 static inline uint32_t
83 translate_stencil_mode(bool enable_0
, bool enable_1
)
86 return enable_1
? VIVS_PE_STENCIL_CONFIG_MODE_TWO_SIDED
87 : VIVS_PE_STENCIL_CONFIG_MODE_ONE_SIDED
;
89 return VIVS_PE_STENCIL_CONFIG_MODE_DISABLED
;
93 static inline uint32_t
94 translate_stencil_op(unsigned 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
;
114 DBG("Unhandled stencil op: %i", stencil_op
);
115 return ETNA_NO_MATCH
;
119 static inline uint32_t
120 translate_blend(unsigned blend
)
125 case PIPE_BLEND_SUBTRACT
:
126 return BLEND_EQ_SUBTRACT
;
127 case PIPE_BLEND_REVERSE_SUBTRACT
:
128 return BLEND_EQ_REVERSE_SUBTRACT
;
134 DBG("Unhandled blend: %i", blend
);
135 return ETNA_NO_MATCH
;
139 static inline uint32_t
140 translate_blend_factor(unsigned blend_factor
)
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
:
178 DBG("Unhandled blend factor: %i", blend_factor
);
179 return ETNA_NO_MATCH
;
183 static inline uint32_t
184 translate_texture_wrapmode(unsigned 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 */
204 DBG("Unhandled texture wrapmode: %i", wrap
);
205 return ETNA_NO_MATCH
;
209 static inline uint32_t
210 translate_texture_mipfilter(unsigned 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
;
220 DBG("Unhandled texture mipfilter: %i", filter
);
221 return ETNA_NO_MATCH
;
225 static inline uint32_t
226 translate_texture_filter(unsigned 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? */
235 DBG("Unhandled texture filter: %i", filter
);
236 return ETNA_NO_MATCH
;
240 /* return a RS "compatible" format for use when copying */
241 static inline enum pipe_format
242 etna_compatible_rs_format(enum pipe_format fmt
)
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
;
248 switch (util_format_get_blocksize(fmt
)) {
250 return PIPE_FORMAT_B4G4R4A4_UNORM
;
252 return PIPE_FORMAT_B8G8R8A8_UNORM
;
259 translate_rb_src_dst_swap(enum pipe_format src
, enum pipe_format dst
)
261 return translate_rs_format_rb_swap(src
) ^ translate_rs_format_rb_swap(dst
);
264 static inline uint32_t
265 translate_depth_format(enum pipe_format fmt
)
267 /* Note: Pipe format convention is LSB to MSB, VIVS is MSB to LSB */
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
;
276 return ETNA_NO_MATCH
;
280 /* render target format for MSAA */
281 static inline uint32_t
282 translate_msaa_format(enum pipe_format fmt
)
284 /* Note: Pipe format convention is LSB to MSB, VIVS is MSB to LSB */
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 */
302 return ETNA_NO_MATCH
;
306 /* Return normalization flag for vertex element format */
307 static inline uint32_t
308 translate_vertex_format_normalize(enum pipe_format fmt
)
310 const struct util_format_description
*desc
= util_format_description(fmt
);
312 return VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF
;
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
;
321 static inline uint32_t
322 translate_index_size(unsigned index_size
)
324 switch (index_size
) {
326 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_CHAR
;
328 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_SHORT
;
330 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_INT
;
332 DBG("Unhandled index size %i", index_size
);
333 return ETNA_NO_MATCH
;
337 static inline uint32_t
338 translate_draw_mode(unsigned 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
;
358 DBG("Unhandled draw mode primitive %i", mode
);
359 return ETNA_NO_MATCH
;
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.
376 etna_layout_multiple(unsigned layout
, unsigned pixel_pipes
, bool rs_align
,
377 unsigned *paddingX
, unsigned *paddingY
, unsigned *halign
)
380 case ETNA_LAYOUT_LINEAR
:
381 *paddingX
= rs_align
? 16 : 4;
383 *halign
= rs_align
? TEXTURE_HALIGN_SIXTEEN
: TEXTURE_HALIGN_FOUR
;
385 case ETNA_LAYOUT_TILED
:
386 *paddingX
= rs_align
? 16 : 4;
388 *halign
= rs_align
? TEXTURE_HALIGN_SIXTEEN
: TEXTURE_HALIGN_FOUR
;
390 case ETNA_LAYOUT_SUPER_TILED
:
393 *halign
= TEXTURE_HALIGN_SUPER_TILED
;
395 case ETNA_LAYOUT_MULTI_TILED
:
397 *paddingY
= 4 * pixel_pipes
;
398 *halign
= TEXTURE_HALIGN_SPLIT_TILED
;
400 case ETNA_LAYOUT_MULTI_SUPERTILED
:
402 *paddingY
= 64 * pixel_pipes
;
403 *halign
= TEXTURE_HALIGN_SPLIT_SUPER_TILED
;
406 DBG("Unhandled layout %i", layout
);
410 static inline void etna_adjust_rs_align(unsigned num_pixelpipes
,
411 unsigned *paddingX
, unsigned *paddingY
)
413 unsigned alignX
= ETNA_RS_WIDTH_MASK
+ 1;
414 unsigned alignY
= (ETNA_RS_HEIGHT_MASK
+ 1) * num_pixelpipes
;
417 *paddingX
= align(*paddingX
, alignX
);
419 *paddingY
= align(*paddingY
, alignY
);
422 static inline uint32_t
423 translate_clear_depth_stencil(enum pipe_format format
, float depth
,
426 uint32_t clear_value
= 0;
428 // XXX util_pack_color
430 case PIPE_FORMAT_Z16_UNORM
:
431 clear_value
= etna_cfloat_to_uintN(depth
, 16);
432 clear_value
|= clear_value
<< 16;
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);
439 DBG("Unhandled pipe format for depth stencil clear: %i", format
);
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. */
448 translate_samples_to_xyscale(int num_samples
, int *xscale_out
, int *yscale_out
,
449 uint32_t *config_out
)
454 switch (num_samples
) {
459 config
= VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_NONE
;
464 config
= VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_2X
;
469 config
= VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_4X
;
476 *xscale_out
= xscale
;
478 *yscale_out
= yscale
;
480 *config_out
= config
;