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_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"
39 #include "util/format/u_format.h"
40 #include "util/u_math.h"
42 /* Returned when there is no match of pipe value to etna value */
43 #define ETNA_NO_MATCH (~0)
45 static inline uint32_t
46 translate_cull_face(unsigned cull_face
, unsigned front_ccw
)
50 return VIVS_PA_CONFIG_CULL_FACE_MODE_OFF
;
52 return front_ccw
? VIVS_PA_CONFIG_CULL_FACE_MODE_CW
53 : VIVS_PA_CONFIG_CULL_FACE_MODE_CCW
;
55 return front_ccw
? VIVS_PA_CONFIG_CULL_FACE_MODE_CCW
56 : VIVS_PA_CONFIG_CULL_FACE_MODE_CW
;
58 DBG("Unhandled cull face mode %i", cull_face
);
63 static inline uint32_t
64 translate_polygon_mode(unsigned polygon_mode
)
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
;
74 DBG("Unhandled polygon mode %i", polygon_mode
);
79 static inline uint32_t
80 translate_stencil_mode(bool enable_0
, bool enable_1
)
83 return enable_1
? VIVS_PE_STENCIL_CONFIG_MODE_TWO_SIDED
84 : VIVS_PE_STENCIL_CONFIG_MODE_ONE_SIDED
;
86 return VIVS_PE_STENCIL_CONFIG_MODE_DISABLED
;
90 static inline uint32_t
91 translate_stencil_op(unsigned 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
;
111 DBG("Unhandled stencil op: %i", stencil_op
);
112 return ETNA_NO_MATCH
;
116 static inline uint32_t
117 translate_blend_factor(unsigned blend_factor
)
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
:
155 DBG("Unhandled blend factor: %i", blend_factor
);
156 return ETNA_NO_MATCH
;
160 static inline uint32_t
161 translate_texture_wrapmode(unsigned 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 */
181 DBG("Unhandled texture wrapmode: %i", wrap
);
182 return ETNA_NO_MATCH
;
186 static inline uint32_t
187 translate_texture_mipfilter(unsigned 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
;
197 DBG("Unhandled texture mipfilter: %i", filter
);
198 return ETNA_NO_MATCH
;
202 static inline uint32_t
203 translate_texture_filter(unsigned filter
)
206 case PIPE_TEX_FILTER_NEAREST
:
207 return TEXTURE_FILTER_NEAREST
;
208 case PIPE_TEX_FILTER_LINEAR
:
209 return TEXTURE_FILTER_LINEAR
;
211 DBG("Unhandled texture filter: %i", filter
);
212 return ETNA_NO_MATCH
;
217 translate_rb_src_dst_swap(enum pipe_format src
, enum pipe_format dst
)
219 return translate_pe_format_rb_swap(src
) ^ translate_pe_format_rb_swap(dst
);
222 static inline uint32_t
223 translate_depth_format(enum pipe_format fmt
)
225 /* Note: Pipe format convention is LSB to MSB, VIVS is MSB to LSB */
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
;
234 return ETNA_NO_MATCH
;
238 /* render target format for MSAA */
239 static inline uint32_t
240 translate_ts_format(enum pipe_format fmt
)
242 /* Note: Pipe format convention is LSB to MSB, VIVS is MSB to LSB */
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 */
269 return ETNA_NO_MATCH
;
273 /* Return normalization flag for vertex element format */
274 static inline uint32_t
275 translate_vertex_format_normalize(enum pipe_format fmt
)
277 const struct util_format_description
*desc
= util_format_description(fmt
);
279 return VIVS_FE_VERTEX_ELEMENT_CONFIG_NORMALIZE_OFF
;
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
;
288 static inline uint32_t
289 translate_output_mode(enum pipe_format fmt
, bool halti5
)
291 const unsigned bits
=
292 util_format_get_component_bits(fmt
, UTIL_FORMAT_COLORSPACE_RGB
, 0);
295 return COLOR_OUTPUT_MODE_UIF32
;
297 if (!util_format_is_pure_integer(fmt
))
298 return COLOR_OUTPUT_MODE_NORMAL
;
300 /* generic integer output mode pre-halti5 (?) */
301 if (bits
== 10 || !halti5
)
302 return COLOR_OUTPUT_MODE_A2B10G10R10UI
;
304 if (util_format_is_pure_sint(fmt
))
305 return bits
== 8 ? COLOR_OUTPUT_MODE_I8
: COLOR_OUTPUT_MODE_I16
;
307 return bits
== 8 ? COLOR_OUTPUT_MODE_U8
: COLOR_OUTPUT_MODE_U16
;
310 static inline uint32_t
311 translate_index_size(unsigned index_size
)
313 switch (index_size
) {
315 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_CHAR
;
317 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_SHORT
;
319 return VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_INT
;
321 DBG("Unhandled index size %i", index_size
);
322 return ETNA_NO_MATCH
;
326 static inline uint32_t
327 translate_draw_mode(unsigned 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
;
347 DBG("Unhandled draw mode primitive %i", mode
);
348 return ETNA_NO_MATCH
;
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.
365 etna_layout_multiple(unsigned layout
, unsigned pixel_pipes
, bool rs_align
,
366 unsigned *paddingX
, unsigned *paddingY
, unsigned *halign
)
369 case ETNA_LAYOUT_LINEAR
:
370 *paddingX
= rs_align
? 16 : 4;
372 *halign
= rs_align
? TEXTURE_HALIGN_SIXTEEN
: TEXTURE_HALIGN_FOUR
;
374 case ETNA_LAYOUT_TILED
:
375 *paddingX
= rs_align
? 16 : 4;
377 *halign
= rs_align
? TEXTURE_HALIGN_SIXTEEN
: TEXTURE_HALIGN_FOUR
;
379 case ETNA_LAYOUT_SUPER_TILED
:
382 *halign
= TEXTURE_HALIGN_SUPER_TILED
;
384 case ETNA_LAYOUT_MULTI_TILED
:
386 *paddingY
= 4 * pixel_pipes
;
387 *halign
= TEXTURE_HALIGN_SPLIT_TILED
;
389 case ETNA_LAYOUT_MULTI_SUPERTILED
:
391 *paddingY
= 64 * pixel_pipes
;
392 *halign
= TEXTURE_HALIGN_SPLIT_SUPER_TILED
;
395 DBG("Unhandled layout %i", layout
);
399 static inline uint32_t
400 translate_clear_depth_stencil(enum pipe_format format
, float depth
,
403 uint32_t clear_value
= 0;
405 // XXX util_pack_color
407 case PIPE_FORMAT_Z16_UNORM
:
408 clear_value
= etna_cfloat_to_uintN(depth
, 16);
409 clear_value
|= clear_value
<< 16;
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);
416 DBG("Unhandled pipe format for depth stencil clear: %i", format
);
421 /* Convert MSAA number of samples to x and y scaling factor.
422 * Return true if supported and false otherwise. */
424 translate_samples_to_xyscale(int num_samples
, int *xscale_out
, int *yscale_out
)
428 switch (num_samples
) {
447 *xscale_out
= xscale
;
449 *yscale_out
= yscale
;
454 static inline uint32_t
455 translate_texture_target(unsigned 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
;
470 DBG("Unhandled texture target: %i", target
);
471 return ETNA_NO_MATCH
;
475 static inline uint32_t
476 translate_texture_compare(enum pipe_compare_func compare_func
)
478 switch (compare_func
) {
479 case PIPE_FUNC_NEVER
:
480 return TEXTURE_COMPARE_FUNC_NEVER
;
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
;
496 unreachable("Invalid compare func");