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