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